π― Selective UI - ARCHITECTURE
Version 1.2 | MIT License
π 1. OVERALL ARCHITECTURE
graph TB
subgraph "PUBLIC API LAYER"
A[Public API] --> B[bind]
A --> C[find]
A --> D[destroy]
A --> E[rebind]
A --> F[effector]
end
subgraph "CORE CONTROLLER"
G[Selective Class]
G --> H[Observer Pattern]
G --> I[Instance Manager]
end
subgraph "COMPONENT LAYER"
J[SelectBox Component]
J --> K[Lifecycle Manager]
J --> L[Event System]
J --> M[Container Builder]
end
subgraph "UTILITY LAYER"
N[Libs Utilities]
N --> O[DOM Helpers]
N --> P[Data Processing]
N --> Q[Animation/Effects]
end
subgraph "STORAGE LAYER"
R[iStorage]
R --> S[Config Manager]
R --> T[Instance Maps]
R --> U[Default Options]
end
subgraph "CALLBACK SYSTEM"
V[CallbackScheduler]
V --> W[Event Queue]
V --> X[Debounce Manager]
end
B --> G
C --> G
D --> G
E --> G
F --> Q
G --> J
G --> R
J --> N
J --> V
N --> R
style A fill:#667eea,stroke:#333,stroke-width:3px,color:#fff
style G fill:#764ba2,stroke:#333,stroke-width:2px,color:#fff
style J fill:#f093fb,stroke:#333,stroke-width:2px,color:#fff
style N fill:#4facfe,stroke:#333,stroke-width:2px,color:#fff
style R fill:#43e97b,stroke:#333,stroke-width:2px,color:#fff
style V fill:#fa709a,stroke:#333,stroke-width:2px,color:#fff
π Describe:
β’ Public API Layer: User interface for interacting with the library
β’ Core Controller: Lifecycle management and component coordination
β’ Component Layer: Build the UI and handle the display logic
β’ Utility Layer: Reusable utility functions
β’ Storage Layer: Manage configurations and save instances
β’ Callback System: Handling events with the debounce mechanism
ποΈ 2. CLASS DIAGRAM
classDiagram
class iStorage {
-Map~Element, BindMap~ bindedMap
-Map~Element, UnbindMap~ unbindedMap
-Array~string~ bindedCommand
-Object defaultConfig
+60+ config options
}
class CallbackScheduler {
-Map executeStored
-Map timerRunner
+on(key, callback, options)
+off(key)
+run(key, params)
+clear(key)
}
class Libs {
-static iStorage _iStorage
+jsCopyObject(obj)
+randomString(length)
+getBinderMap(element)
+setBinderMap(element, data)
+buildConfig(element, options)
+100+ utility methods
}
class Selective {
+bind(query, options)
+find(query) ActionAPI
+destroy(query)
+rebind(query, options)
+Observer()
-applySelectBox(element, options)
}
class SelectBox {
-HTMLSelectElement element
-Selective selective
-Container container
-CallbackScheduler events
+mount()
+unmount()
+on(event, callback)
+getAction() ActionAPI
}
class ActionAPI {
+open()
+close()
+toggle()
+setValue(value)
+getValue()
+setData(data)
+getData()
+refresh()
+reload()
+enable()
+disable()
+search(query)
+isEmpty boolean
+isOpen boolean
}
class Effector {
-HTMLElement element
+show()
+hide()
+fadeIn()
+fadeOut()
+slideUp()
+slideDown()
+position(config)
}
Selective --> Libs : uses
Selective --> iStorage : manages
Selective --> SelectBox : creates
SelectBox --> CallbackScheduler : uses
SelectBox --> ActionAPI : provides
SelectBox --> Libs : uses
Libs --> iStorage : accesses
Effector --> Libs : uses
π Relationships between Classes:
β’ Selective: The main controller coordinates the entire system
β’ SelectBox: Component core renders UI for each select element
β’ Libs: Utility class provides 100+ helper methods
β’ iStorage: Singleton stores configuration and instance maps
β’ CallbackScheduler: Manage event callbacks with Debounce
β’ ActionAPI: Public interface for controlling select boxes
π 3. LIFECYCLE FLOW
sequenceDiagram
participant User
participant API as Public API
participant SEL as Selective
participant SB as SelectBox
participant CB as CallbackScheduler
participant DOM
User->>API: bind(".my-select", options)
API->>SEL: bind(query, options)
SEL->>DOM: querySelector(query)
DOM-->>SEL: HTMLSelectElement[]
loop For each element
SEL->>SEL: buildConfig(element, options)
SEL->>SB: new SelectBox(element)
SB->>CB: Initialize event system
SB->>DOM: Create UI container
SB->>CB: Trigger "load" event
CB-->>User: on.load callbacks
SB->>SEL: Return ActionAPI
SEL->>SEL: Store in bindedMap
end
SEL-->>API: Binding complete
API-->>User: Ready to use
Note over User,DOM: User Interaction Phase
User->>DOM: Click select box
DOM->>SB: mousedown event
SB->>CB: Trigger "beforeShow"
CB-->>User: on.beforeShow callbacks
SB->>DOM: Toggle panel visibility
SB->>CB: Trigger "show"
CB-->>User: on.show callbacks
User->>DOM: Select option
DOM->>SB: click event
SB->>CB: Trigger "beforeChange"
CB-->>User: on.beforeChange callbacks
SB->>SB: Update value
SB->>DOM: Update UI
SB->>CB: Trigger "change"
CB-->>User: on.change callbacks
Note over User,DOM: Cleanup Phase
User->>API: destroy(".my-select")
API->>SEL: destroy(query)
SEL->>SB: unmount()
SB->>CB: Clear all callbacks
SB->>DOM: Remove UI elements
SB->>SEL: Remove from bindedMap
SEL-->>API: Destroyed
API-->>User: Cleanup complete
π― Event Lifecycle Order:
- load β When creating a SelectBox
- beforeShow β Before opening the dropdown
- show β After opening the dropdown
- beforeChange β Before changing the value
- change β After changing the value
- beforeClose β Before closing the dropdown
- close β After closing the dropdown
π 4. DATA FLOW
graph LR
subgraph "INPUT SOURCES"
A[HTML Select Options]
B[JSON Array]
C[AJAX Response]
D[Direct setData]
end
subgraph "DATA PROCESSING"
E[Data Parser]
E --> F[Normalize Format]
F --> G[Apply Filters]
G --> H[Group by Category]
H --> I[Sort Items]
end
subgraph "STORAGE"
J[(Internal Data Store)]
J --> K[Selected Items]
J --> L[Available Options]
J --> M[Search Cache]
end
subgraph "RENDERING"
N[Virtual Scroll Engine]
N --> O[Calculate Viewport]
O --> P[Render Visible Items]
P --> Q[Apply Search Highlight]
end
subgraph "OUTPUT"
R[DOM Update]
R --> S[Update Select Value]
R --> T[Update UI Display]
R --> U[Trigger Events]
end
A --> E
B --> E
C --> E
D --> E
I --> J
J --> N
Q --> R
style A fill:#e3f2fd,stroke:#1976d2
style B fill:#e3f2fd,stroke:#1976d2
style C fill:#e3f2fd,stroke:#1976d2
style D fill:#e3f2fd,stroke:#1976d2
style J fill:#fff3e0,stroke:#f57c00
style R fill:#e8f5e9,stroke:#388e3c
π Data Flow Process:
β’ Input: Multiple data sources (HTML, JSON, AJAX)
β’ Processing: Normalize, filter, group, sort
β’ Storage: Internal storage with search cache
β’ Rendering: Virtual scroll only renders visible items
β’ Output: Update the DOM and trigger events
π¨ 5. UI COMPONENT STRUCTURE
graph TD
A[.seui-container] --> B[.seui-view]
A --> C[.seui-panel]
B --> D[.seui-placeholder]
B --> E[.seui-accessory]
B --> F[.seui-arrow]
D --> D1[Selected Text/Image]
E --> E1[Multi-select Chips]
E --> E2[Deselect Buttons]
F --> F1[Dropdown Icon]
C --> G[.seui-search]
C --> H[.seui-selectall]
C --> I[.seui-optionlist]
C --> J[.seui-loading]
G --> G1[Search Input]
G --> G2[Clear Button]
H --> H1[Select All Button]
H --> H2[Deselect All Button]
I --> I1[Virtual Scroll Container]
I1 --> I2[.seui-option]
I1 --> I3[.seui-group]
I2 --> I4[Checkbox/Radio]
I2 --> I5[Image Optional]
I2 --> I6[Label Text]
J --> J1[Loading Spinner]
J --> J2[Loading Text]
style A fill:#667eea,stroke:#333,stroke-width:3px,color:#fff
style B fill:#f093fb,stroke:#333,stroke-width:2px
style C fill:#4facfe,stroke:#333,stroke-width:2px
style I1 fill:#43e97b,stroke:#333,stroke-width:2px
π Component Hierarchy:
β’ seui-container: The main container encloses everything
β’ seui-view: The section displaying the selected value (clickable)
β’ seui-panel: The dropdown panel contains options
β’ seui-optionlist: Options list with virtual scroll
β’ seui-accessory: Chips display multi-select items
β‘ 6. EVENT SYSTEM
graph TB
subgraph "EVENT REGISTRATION"
A[User Code]
B[CallbackScheduler]
A --> |on.load / on.beforeShow / on.show / on.beforeChange / on.change / on.beforeClose / on.close| B
end
subgraph "CALLBACK SCHEDULER"
B --> C[executeStored Map]
C --> D[Key: EventType]
D --> E[Array of Callbacks]
E --> F[Callback 1]
E --> G[Callback 2]
E --> H[Callback N]
end
subgraph "DEBOUNCE SYSTEM"
I[timerRunner Map]
I --> J[Key: EventType]
J --> K[Map Index: TimerID]
K --> L[setTimeout]
end
subgraph "EXECUTION FLOW"
M[Trigger Event] --> N{Has Callbacks?}
N -->|Yes| O[Schedule with Debounce]
N -->|No| P[Skip]
O --> Q[Clear Previous Timer]
Q --> R[Start New Timer]
R --> S[Execute Callback]
S --> T{Once Flag?}
T -->|Yes| U[Remove Callback]
T -->|No| V[Keep for Reuse]
end
subgraph "EVENT TOKEN"
W[EventToken] --> X[isContinue]
W --> Y[stopPropagation]
W --> Z[preventDefault]
end
B -.-> I
S --> W
style B fill:#fa709a,stroke:#333,stroke-width:2px,color:#fff
style I fill:#ffd89b,stroke:#333,stroke-width:2px
style M fill:#667eea,stroke:#333,stroke-width:2px,color:#fff
style W fill:#43e97b,stroke:#333,stroke-width:2px
π Event System Features:
β’ Debounce: Each callback has its own timer (default 50ms)
β’ Once Flag: The callback only runs once and then deletes itself
β’ Event Token: Control propagation as DOM events
β’ Async Support: Callbacks can return Promise
β’ Order Preservation: Callbacks run in the order of registration
ποΈ 7. STATE MANAGEMENT
stateDiagram-v2
[*] --> Unbound: Create Element
Unbound --> Binding: bind() called
Binding --> Bound: SelectBox mounted
Bound --> Closed: Initial state
Closed --> Opening: User clicks
Opening --> Opened: Animation complete
Opened --> Searching: User types
Searching --> Opened: Search complete
Opened --> Selecting: User clicks option
Selecting --> Changed: Value updated
Changed --> Closed: autoclose=true
Changed --> Opened: autoclose=false
Opened --> Closing: Click outside / ESC
Closing --> Closed: Animation complete
Closed --> Disabled: disable() called
Disabled --> Closed: enable() called
Bound --> Loading: AJAX request
Loading --> Bound: Data received
Bound --> Unbinding: destroy() called
Unbinding --> Unbound: Cleanup complete
Unbound --> [*]: Element removed
note right of Bound
State Properties:
- isOpen
- isDisabled
- isLoading
- isEmpty
- hasSearch
- selectedValues[]
end note
π State Transitions:
β’ Unbound β Bound: Initialization via bind()
β’ Closed β Opened: Toggle dropdown visibility
β’ Searching: Active search mode with filter
β’ Loading: AJAX data fetching
β’ Disabled: No interaction allowed
β’ Changed: Value has changed, trigger events
π 8. VIRTUAL SCROLL MECHANISM
graph TB
subgraph "INITIALIZATION"
A[Total Items: 10000] --> B[Calculate Item Height]
B --> C[Calculate Viewport Height]
C --> D[Items Per View = Viewport / ItemHeight]
end
subgraph "SCROLL CALCULATION"
E[Scroll Event] --> F[Get ScrollTop Position]
F --> G[Calculate Start Index]
G --> H[Calculate End Index]
H --> I[Add Buffer Items]
end
subgraph "RENDERING"
I --> J{Items Changed?}
J -->|Yes| K[Update Visible Range]
J -->|No| L[Skip Update]
K --> M[Render Items Start-End]
M --> N[Set Top Offset]
N --> O[Set Total Height]
end
subgraph "OPTIMIZATION"
P[Debounce Scroll: 16ms]
Q[Reuse DOM Elements]
R[Minimal Reflows]
S[RequestAnimationFrame]
end
E --> P
M --> Q
M --> R
N --> S
style A fill:#667eea,stroke:#333,stroke-width:2px,color:#fff
style E fill:#fa709a,stroke:#333,stroke-width:2px,color:#fff
style M fill:#43e97b,stroke:#333,stroke-width:2px
style P fill:#ffd89b,stroke:#333,stroke-width:2px
π Virtual Scroll Benefits:
β’ Performance: Render only 20-30 items instead of 10,000
β’ Memory: Reduce DOM nodes, speed up browser paint
β’ Smooth: 60fps scrolling with buffer items
β’ Dynamic: Automatic calculation when resizing
π― Virtual Scroll Formula:
- startIndex = Math.floor(scrollTop / itemHeight)
- endIndex = startIndex + itemsPerView + buffer
- topOffset = startIndex Γ itemHeight
- totalHeight = totalItems Γ itemHeight
π 9. AJAX DATA LOADING FLOW
sequenceDiagram
participant User
participant SB as SelectBox
participant AJAX as AJAX Handler
participant Server
participant UI as UI Renderer
User->>SB: Open dropdown
SB->>SB: Check ajax config
alt AJAX Configured
SB->>UI: Show loading state
UI-->>User: Display "Processing..."
SB->>AJAX: Prepare request
AJAX->>AJAX: Build URL + headers
AJAX->>Server: fetch(url, options)
alt Success Response
Server-->>AJAX: JSON data
AJAX->>AJAX: dataTransform(response)
AJAX->>SB: Normalized data[]
SB->>SB: setData(data)
SB->>UI: Render options
UI-->>User: Display dropdown
else Error Response
Server-->>AJAX: Error
AJAX->>SB: Handle error
SB->>UI: Show error message
UI-->>User: Display "Error loading"
end
else No AJAX
SB->>SB: Use existing data
SB->>UI: Render options
UI-->>User: Display dropdown
end
User->>UI: Select option
UI->>SB: Update value
SB->>User: Trigger change event
π AJAX Configuration:
β’ url: API endpoint
β’ method: GET/POST/PUT/DELETE
β’ headers: Custom headers (auth, content-type)
β’ data: Request payload
β’ dataTransform: Function Δα» transform response
βοΈ 10. CONFIGURATION HIERARCHY
graph TB
A[Default Config
iStorage.defaultConfig] --> B[Merge Priority]
C[Data Attributes
data-*] --> B
D[bind Options
bind query, options] --> B
B --> E[Final Config]
subgraph "Default Config Categories"
F[Visual
width, height, colors]
G[Behavior
multiple, searchable]
H[Text/i18n
placeholder, messages]
I[Performance
virtualScroll, debounce]
J[Events
on.load, on.change...]
end
E --> K{Priority Order}
K -->|1. Highest| D
K -->|2. Medium| C
K -->|3. Lowest| A
E --> L[Apply to SelectBox]
style A fill:#e3f2fd,stroke:#1976d2
style C fill:#fff3e0,stroke:#f57c00
style D fill:#e8f5e9,stroke:#388e3c
style E fill:#667eea,stroke:#333,stroke-width:3px,color:#fff
π Config Priority (high β low):
1. bind() options - Highest priority
2. data-* attributes - HTML attributes
3. defaultConfig - Default value
π― Key Configuration Options:
- Visual: width, height, minWidth, panelHeight, imageMode
- Behavior: multiple, searchable, autoclose, disabled
- Selection: selectall, maxSelected, keepSelected
- Text: placeholder, textLoading, textNotFound
- Performance: virtualScroll, animationtime, delaysearchtime
- AJAX: ajax.url, ajax.method, ajax.dataTransform
- Events: on.load, on.change, on.show, on.close...
π§Ή 11. MEMORY MANAGEMENT & CLEANUP
graph TB
subgraph "BINDING PHASE"
A[bind Called] --> B[Create SelectBox]
B --> C[Mount DOM Elements]
C --> D[Attach Event Listeners]
D --> E[Store in bindedMap]
E --> F[Add to bindedCommand]
end
subgraph "RUNTIME PHASE"
G[Observer Watching] --> H{DOM Mutation?}
H -->|Element Removed| I[Auto Cleanup]
H -->|Element Added| J[Auto Rebind]
end
subgraph "UNBINDING PHASE"
K[destroy Called] --> L{Unbind Target}
L -->|Specific Query| M[Find Elements]
L -->|null All| N[Get All Instances]
M --> O[For Each Element]
N --> O
O --> P[Call unmount]
P --> Q[Remove Event Listeners]
Q --> R[Clear Callbacks]
R --> S[Remove DOM Elements]
S --> T[Delete from bindedMap]
T --> U[Remove from bindedCommand]
U --> V[Store in unbindedMap]
end
subgraph "GARBAGE COLLECTION"
W[Periodic Check] --> X[Clean unbindedMap]
X --> Y[Remove Weak References]
Y --> Z[Free Memory]
end
I --> P
V --> W
style A fill:#43e97b,stroke:#333,stroke-width:2px
style K fill:#fa709a,stroke:#333,stroke-width:2px,color:#fff
style G fill:#667eea,stroke:#333,stroke-width:2px,color:#fff
style W fill:#ffd89b,stroke:#333,stroke-width:2px
π Memory Management Features:
β’ Automatic Cleanup: The Observer automatically detects when an element is removed
β’ Event Cleanup: All listeners are removed when destroyed
β’ Callback Cleanup: CallbackScheduler clear timers & callbacks
β’ DOM Cleanup: Remove all created UI elements
β’ Map Cleanup: Remove references from boundedMap/unbindedMap
π¦ 12. MODULE SYSTEM & BUILD OUTPUT
graph LR
subgraph "SOURCE CODE"
A[TypeScript/ES6+
Source Files]
end
subgraph "BUILD PROCESS"
B[Compiler
Vite/Rollup]
B --> C[Tree Shaking]
B --> D[Minification]
B --> E[Polyfills]
end
subgraph "OUTPUT FORMATS"
F[ESM
selective-ui.esm.js
419KB]
M[ESM
selective-ui.esm.min.js
68KB]
G[UMD
selective-ui.umd.js
463KB]
N[UMD
selective-ui.min.js
69KB]
H[CSS
selective-ui.css]
O[CSS
selective-ui.min.css]
end
subgraph "USAGE"
I[ES Module
import from 'selective-ui']
J[CommonJS
require 'selective-ui']
K[Browser Global
window.SelectiveUI]
L[CSS Link
link rel=stylesheet]
end
A --> B
C --> F
C --> G
C --> M
C --> N
D --> M
E --> G
E --> N
D --> N
F --> I
G --> J
G --> K
H --> L
M --> I
N --> J
N --> K
O --> L
style F fill:#43e97b,stroke:#333,stroke-width:2px
style M fill:#43e97b,stroke:#333,stroke-width:2px
style G fill:#667eea,stroke:#333,stroke-width:2px,color:#fff
style N fill:#667eea,stroke:#333,stroke-width:2px,color:#fff
style H fill:#fa709a,stroke:#333,stroke-width:2px,color:#fff
style O fill:#fa709a,stroke:#333,stroke-width:2px,color:#fff
π Build Outputs:
β’ ESM (284KB): Modern ES modules, tree-shakeable
β’ UMD (316KB): Universal format, browser compatible
β’ CSS: Component styles, theme variables
π― Usage Examples:
- ES Module: import { bind } from 'selective-ui'
- CommonJS: const { bind } = require('selective-ui')
- Browser: <script src="selective-ui.min.js">
- CDN: https://cdn.jsdelivr.net/npm/selective-ui