@simplysm/solid 13.0.96 → 13.0.98
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +314 -123
- package/docs/data.md +216 -0
- package/docs/disclosure.md +164 -0
- package/docs/display.md +94 -0
- package/docs/features.md +211 -625
- package/docs/feedback.md +210 -0
- package/docs/form-control.md +537 -0
- package/docs/helpers.md +168 -0
- package/docs/hooks.md +143 -0
- package/docs/layout.md +182 -0
- package/docs/providers.md +177 -0
- package/docs/styles.md +127 -0
- package/package.json +19 -26
- package/docs/display-feedback.md +0 -404
- package/docs/form-controls.md +0 -587
- package/docs/layout-data.md +0 -392
- package/docs/providers-hooks.md +0 -516
package/docs/hooks.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Hooks
|
|
2
|
+
|
|
3
|
+
Source: `src/hooks/*.ts`
|
|
4
|
+
|
|
5
|
+
## useLocalStorage
|
|
6
|
+
|
|
7
|
+
localStorage-backed reactive signal. Keys are prefixed with `ConfigContext.clientName`.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
function useLocalStorage<TValue>(
|
|
11
|
+
key: string,
|
|
12
|
+
initialValue?: TValue,
|
|
13
|
+
): [Accessor<TValue | undefined>, StorageSetter<TValue>];
|
|
14
|
+
|
|
15
|
+
type StorageSetter<TValue> = (
|
|
16
|
+
value: TValue | undefined | ((prev: TValue | undefined) => TValue | undefined),
|
|
17
|
+
) => TValue | undefined;
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- Always uses localStorage regardless of `SyncStorageProvider`.
|
|
21
|
+
- Used for device-specific data (auth tokens, local state).
|
|
22
|
+
- Setting `undefined` removes the item from localStorage.
|
|
23
|
+
|
|
24
|
+
## useSyncConfig
|
|
25
|
+
|
|
26
|
+
Storage-synced configuration signal. Uses `SyncStorageProvider` adapter if available, falls back to localStorage.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
function useSyncConfig<TValue>(
|
|
30
|
+
key: string,
|
|
31
|
+
defaultValue: TValue,
|
|
32
|
+
): [Accessor<TValue>, Setter<TValue>, Accessor<boolean>];
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- Returns `[value, setValue, ready]`.
|
|
36
|
+
- `ready()` becomes `true` after the initial value is loaded from storage.
|
|
37
|
+
- When the adapter changes via `useSyncStorage().configure()`, re-reads from the new adapter.
|
|
38
|
+
- Used for data that should persist and sync across devices (theme, preferences, DataSheet configs).
|
|
39
|
+
|
|
40
|
+
## useLogger
|
|
41
|
+
|
|
42
|
+
Logging hook with pluggable adapter. Falls back to `consola` if `LoggerProvider` is not present.
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
interface Logger {
|
|
46
|
+
log: (...args: unknown[]) => void;
|
|
47
|
+
info: (...args: unknown[]) => void;
|
|
48
|
+
warn: (...args: unknown[]) => void;
|
|
49
|
+
error: (...args: unknown[]) => void;
|
|
50
|
+
configure: (fn: (origin: LogAdapter) => LogAdapter) => void;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function useLogger(): Logger;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`configure` is only usable inside `LoggerProvider`.
|
|
57
|
+
|
|
58
|
+
## createControllableSignal
|
|
59
|
+
|
|
60
|
+
Signal hook supporting the controlled/uncontrolled pattern. Used extensively by form components.
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
function createControllableSignal<TValue>(options: {
|
|
64
|
+
value: Accessor<TValue>;
|
|
65
|
+
onChange: Accessor<((value: TValue) => void) | undefined>;
|
|
66
|
+
}): [Accessor<TValue>, (newValue: TValue | ((prev: TValue) => TValue)) => TValue];
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- When `onChange` is provided: controlled mode, value managed externally.
|
|
70
|
+
- When `onChange` returns `undefined`: uncontrolled mode, uses internal state.
|
|
71
|
+
- Supports functional setter: `setValue(prev => !prev)`.
|
|
72
|
+
|
|
73
|
+
## createControllableStore
|
|
74
|
+
|
|
75
|
+
Store hook supporting the controlled/uncontrolled pattern. Uses `solid-js/store` for fine-grained reactivity.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
function createControllableStore<TValue extends object>(options: {
|
|
79
|
+
value: () => TValue;
|
|
80
|
+
onChange: () => ((value: TValue) => void) | undefined;
|
|
81
|
+
}): [TValue, SetStoreFunction<TValue>];
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
- Supports all `SetStoreFunction` overloads (path-based, produce, reconcile).
|
|
85
|
+
- In controlled mode: calls `onChange` with a deep clone when the store changes.
|
|
86
|
+
|
|
87
|
+
## createIMEHandler
|
|
88
|
+
|
|
89
|
+
IME composition handling hook. Delays value commits during IME composition (e.g., Korean input) to prevent DOM recreation and composition breakage.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
function createIMEHandler(setValue: (value: string) => void): {
|
|
93
|
+
composingValue: Accessor<string | null>;
|
|
94
|
+
handleCompositionStart: () => void;
|
|
95
|
+
handleInput: (value: string, isComposing: boolean) => void;
|
|
96
|
+
handleCompositionEnd: (value: string) => void;
|
|
97
|
+
flushComposition: () => void;
|
|
98
|
+
};
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
- During composition: only `composingValue` is updated (for display).
|
|
102
|
+
- On `compositionEnd`: delays `setValue` via `setTimeout(0)`.
|
|
103
|
+
- `flushComposition()`: immediately commits any pending value.
|
|
104
|
+
|
|
105
|
+
## createMountTransition
|
|
106
|
+
|
|
107
|
+
Mount/unmount animation state hook.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
function createMountTransition(open: () => boolean): {
|
|
111
|
+
mounted: () => boolean;
|
|
112
|
+
animating: () => boolean;
|
|
113
|
+
unmount: () => void;
|
|
114
|
+
};
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
- `open=true`: immediately sets `mounted=true`, then `animating=true` after double `requestAnimationFrame`.
|
|
118
|
+
- `open=false`: immediately sets `animating=false`, then `mounted=false` after `transitionend` or 200ms fallback.
|
|
119
|
+
- Use `mounted()` for DOM rendering, `animating()` for CSS class toggling.
|
|
120
|
+
- Call `unmount()` to manually remove from DOM (e.g., in `onTransitionEnd`).
|
|
121
|
+
|
|
122
|
+
## useRouterLink
|
|
123
|
+
|
|
124
|
+
Router navigation hook supporting modifier keys (Ctrl+click, Shift+click).
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
interface RouterLinkOptions {
|
|
128
|
+
href: string;
|
|
129
|
+
state?: Record<string, unknown>;
|
|
130
|
+
window?: {
|
|
131
|
+
width?: number; // default: 800
|
|
132
|
+
height?: number; // default: 800
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function useRouterLink(): (
|
|
137
|
+
options: RouterLinkOptions,
|
|
138
|
+
) => (e: MouseEvent | KeyboardEvent) => void;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
- Normal click: SPA routing via `useNavigate`.
|
|
142
|
+
- Ctrl/Alt + click: opens in new tab.
|
|
143
|
+
- Shift + click: opens in new window with specified dimensions.
|
package/docs/layout.md
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# Layout
|
|
2
|
+
|
|
3
|
+
Source: `src/components/layout/**/*.tsx`
|
|
4
|
+
|
|
5
|
+
## FormGroup
|
|
6
|
+
|
|
7
|
+
Vertical or inline form field group.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
interface FormGroupProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
|
11
|
+
inline?: boolean; // horizontal layout with wrapping
|
|
12
|
+
}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Sub-components
|
|
16
|
+
|
|
17
|
+
- **`FormGroup.Item`** -- Labeled form item.
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
interface FormGroupItemProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
|
21
|
+
label?: JSX.Element;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## FormTable
|
|
26
|
+
|
|
27
|
+
Table-based form layout using `<table>` elements.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
interface FormTableProps extends JSX.HTMLAttributes<HTMLTableElement> {}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Sub-components
|
|
34
|
+
|
|
35
|
+
- **`FormTable.Row`** -- Table row. Extends `JSX.HTMLAttributes<HTMLTableRowElement>`.
|
|
36
|
+
- **`FormTable.Item`** -- Labeled table cell. When `label` is omitted, the cell spans the label column.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
interface FormTableItemProps extends JSX.TdHTMLAttributes<HTMLTableCellElement> {
|
|
40
|
+
label?: JSX.Element;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Sidebar
|
|
45
|
+
|
|
46
|
+
Collapsible sidebar panel. Must be used inside `Sidebar.Container`.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
interface SidebarProps extends JSX.HTMLAttributes<HTMLElement> {
|
|
50
|
+
children: JSX.Element;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Sidebar.Container
|
|
55
|
+
|
|
56
|
+
Layout container that holds the Sidebar and content area. Provides `SidebarContext` for toggle state. Parent element must have height specified (use `h-full`).
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
interface SidebarContainerProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
|
60
|
+
children: JSX.Element;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
- Desktop (640px+): uses `padding-left` transition to expand/collapse.
|
|
65
|
+
- Mobile (<640px): renders backdrop overlay. Auto-closes on navigation.
|
|
66
|
+
|
|
67
|
+
### Sidebar.Menu
|
|
68
|
+
|
|
69
|
+
Recursive sidebar menu with route-based selection.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
interface SidebarMenuProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
73
|
+
menus: AppMenu[];
|
|
74
|
+
defaultOpen?: boolean; // expand all nested menus on initial render (default: false)
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
- Parent items of the selected route auto-expand on initial render.
|
|
79
|
+
- External links (containing `://`) open in a new tab.
|
|
80
|
+
|
|
81
|
+
### Sidebar.User
|
|
82
|
+
|
|
83
|
+
User information area with optional dropdown menu.
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
interface SidebarUserProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "onClick"> {
|
|
87
|
+
name: string;
|
|
88
|
+
icon?: Component<TablerIconProps>;
|
|
89
|
+
description?: string;
|
|
90
|
+
menus?: SidebarUserMenu[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface SidebarUserMenu {
|
|
94
|
+
title: string;
|
|
95
|
+
onClick: () => void;
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### useSidebar()
|
|
100
|
+
|
|
101
|
+
Hook to access sidebar toggle state. Throws if used outside `Sidebar.Container`.
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
function useSidebar(): {
|
|
105
|
+
toggle: Accessor<boolean>;
|
|
106
|
+
setToggle: Setter<boolean>;
|
|
107
|
+
};
|
|
108
|
+
// Also available: useSidebar.optional() returns undefined if no context
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Topbar
|
|
112
|
+
|
|
113
|
+
Top navigation bar. Automatically shows a sidebar toggle button if used inside `Sidebar.Container`.
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
interface TopbarProps extends JSX.HTMLAttributes<HTMLElement> {
|
|
117
|
+
children: JSX.Element;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Topbar.Container
|
|
122
|
+
|
|
123
|
+
Vertical layout container wrapping Topbar and content area. Provides `TopbarContext` for actions.
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
interface TopbarContainerProps extends JSX.HTMLAttributes<HTMLDivElement> {
|
|
127
|
+
children: JSX.Element;
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Topbar.Menu
|
|
132
|
+
|
|
133
|
+
Dropdown navigation menu. Shows desktop buttons on 640px+ and a hamburger menu on mobile.
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
interface TopbarMenuProps extends Omit<JSX.HTMLAttributes<HTMLElement>, "children"> {
|
|
137
|
+
menus: TopbarMenuItem[];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface TopbarMenuItem {
|
|
141
|
+
title: string;
|
|
142
|
+
href?: string;
|
|
143
|
+
icon?: Component<IconProps>;
|
|
144
|
+
children?: TopbarMenuItem[];
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Topbar.User
|
|
149
|
+
|
|
150
|
+
User information component with optional dropdown menu.
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
interface TopbarUserProps extends Omit<JSX.HTMLAttributes<HTMLDivElement>, "onClick"> {
|
|
154
|
+
menus?: TopbarUserMenu[];
|
|
155
|
+
children: JSX.Element;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
interface TopbarUserMenu {
|
|
159
|
+
title: string;
|
|
160
|
+
onClick: () => void;
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Topbar.Actions
|
|
165
|
+
|
|
166
|
+
Renders action elements registered by `useTopbarActions()`.
|
|
167
|
+
|
|
168
|
+
### useTopbarActions()
|
|
169
|
+
|
|
170
|
+
Register action elements that appear in the Topbar. Automatically cleaned up on component unmount.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
function useTopbarActions(accessor: () => JSX.Element): void;
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### useTopbarActionsAccessor()
|
|
177
|
+
|
|
178
|
+
Read the current topbar actions signal.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
function useTopbarActionsAccessor(): Accessor<JSX.Element | undefined>;
|
|
182
|
+
```
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Providers
|
|
2
|
+
|
|
3
|
+
Source: `src/providers/**/*.tsx`
|
|
4
|
+
|
|
5
|
+
## ConfigContext / ConfigProvider
|
|
6
|
+
|
|
7
|
+
App-level configuration providing the `clientName` used as a prefix for storage keys.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
interface AppConfig {
|
|
11
|
+
clientName: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ConfigContext: Context<AppConfig>;
|
|
15
|
+
|
|
16
|
+
function useConfig(): AppConfig;
|
|
17
|
+
|
|
18
|
+
const ConfigProvider: ParentComponent<{ clientName: string }>;
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## SyncStorageProvider / useSyncStorage
|
|
22
|
+
|
|
23
|
+
Pluggable storage provider. Components use this adapter for persistent storage (localStorage fallback when no adapter is configured).
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
interface StorageAdapter {
|
|
27
|
+
getItem: (key: string) => Promise<string | null>;
|
|
28
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
29
|
+
removeItem: (key: string) => Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface SyncStorageContextValue {
|
|
33
|
+
adapter: Accessor<StorageAdapter | undefined>;
|
|
34
|
+
configure: (adapter: StorageAdapter | undefined) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const SyncStorageContext: Context<SyncStorageContextValue>;
|
|
38
|
+
|
|
39
|
+
function useSyncStorage(): SyncStorageContextValue | undefined;
|
|
40
|
+
|
|
41
|
+
const SyncStorageProvider: ParentComponent;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## LoggerProvider
|
|
45
|
+
|
|
46
|
+
Logging adapter provider. Allows plugging in custom log writers.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
interface LogAdapter {
|
|
50
|
+
write: (level: "log" | "info" | "warn" | "error", ...args: unknown[]) => void | Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface LoggerContextValue {
|
|
54
|
+
adapter: Accessor<LogAdapter | undefined>;
|
|
55
|
+
configure: (fn: (origin: LogAdapter) => LogAdapter) => void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const LoggerContext: Context<LoggerContextValue>;
|
|
59
|
+
|
|
60
|
+
const LoggerProvider: ParentComponent;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## ThemeContext / ThemeProvider / useTheme
|
|
64
|
+
|
|
65
|
+
Light/dark/system theme management. Persists mode to synced storage.
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
69
|
+
type ResolvedTheme = "light" | "dark";
|
|
70
|
+
|
|
71
|
+
interface ThemeContextValue {
|
|
72
|
+
mode: Accessor<ThemeMode>;
|
|
73
|
+
resolved: Accessor<ResolvedTheme>;
|
|
74
|
+
setMode: (mode: ThemeMode) => void;
|
|
75
|
+
cycleMode: () => void;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function useTheme(): ThemeContextValue;
|
|
79
|
+
|
|
80
|
+
const ThemeProvider: ParentComponent;
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- `cycleMode()`: light -> system -> dark -> light.
|
|
84
|
+
- `resolved`: the actual applied theme after resolving "system" via `prefers-color-scheme`.
|
|
85
|
+
|
|
86
|
+
## ServiceClientProvider / useServiceClient
|
|
87
|
+
|
|
88
|
+
Service client connection provider for `@simplysm/service-client`.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
interface ServiceClientContextValue {
|
|
92
|
+
client: Accessor<SdServiceClient | undefined>;
|
|
93
|
+
connected: Accessor<boolean>;
|
|
94
|
+
configure: (url: string) => void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const ServiceClientContext: Context<ServiceClientContextValue>;
|
|
98
|
+
|
|
99
|
+
function useServiceClient(): ServiceClientContextValue;
|
|
100
|
+
|
|
101
|
+
const ServiceClientProvider: ParentComponent;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## SystemProvider
|
|
105
|
+
|
|
106
|
+
Composite provider that bundles commonly used providers together.
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const SystemProvider: ParentComponent<{
|
|
110
|
+
clientName: string;
|
|
111
|
+
busyVariant?: BusyVariant;
|
|
112
|
+
}>;
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Internally wraps: `ConfigProvider`, `I18nProvider`, `SyncStorageProvider`, `LoggerProvider`, `ThemeProvider`, `BusyProvider`, `NotificationProvider`, `DialogProvider`, `PrintProvider`, `ErrorLoggerProvider`, `ClipboardProvider`, `PwaUpdateProvider`.
|
|
116
|
+
|
|
117
|
+
## I18nProvider / useI18n
|
|
118
|
+
|
|
119
|
+
Internationalization provider with flat dictionary-based translations.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
interface I18nContextValue {
|
|
123
|
+
locale: Accessor<string>;
|
|
124
|
+
t: (key: string, params?: Record<string, string>) => string;
|
|
125
|
+
configure: (options: I18nConfigureOptions) => void;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface I18nConfigureOptions {
|
|
129
|
+
locale?: string;
|
|
130
|
+
dict?: Record<string, unknown>; // nested dict, auto-flattened
|
|
131
|
+
flatDict?: FlatDict; // pre-flattened dict
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
type FlatDict = Record<string, string>;
|
|
135
|
+
|
|
136
|
+
function useI18n(): I18nContextValue;
|
|
137
|
+
|
|
138
|
+
const I18nProvider: ParentComponent;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
- `t("key", { name: "value" })`: interpolates `{name}` placeholders.
|
|
142
|
+
- `configure()`: merges new dictionaries into existing translations.
|
|
143
|
+
|
|
144
|
+
## SharedDataProvider / useSharedData
|
|
145
|
+
|
|
146
|
+
Shared data cache provider. Loads and caches data from service, auto-refreshes on change events.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
interface SharedDataDefinition<TData> {
|
|
150
|
+
key: string;
|
|
151
|
+
loader: () => Promise<TData[]>;
|
|
152
|
+
getKey: (item: TData) => string | number;
|
|
153
|
+
getSearchText?: (item: TData) => string;
|
|
154
|
+
getChildren?: (item: TData, allItems: TData[]) => TData[];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
interface SharedDataAccessor<TData> {
|
|
158
|
+
items: Accessor<TData[]>;
|
|
159
|
+
loading: Accessor<boolean>;
|
|
160
|
+
refresh: () => Promise<void>;
|
|
161
|
+
getByKey: (key: string | number) => TData | undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function useSharedData<TSharedData extends Record<string, unknown>>(): SharedDataValue<TSharedData>;
|
|
165
|
+
|
|
166
|
+
function SharedDataProvider(props: { children: JSX.Element }): JSX.Element;
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### SharedDataChangeEvent
|
|
170
|
+
|
|
171
|
+
Event emitted when shared data changes, triggering refresh.
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
const SharedDataChangeEvent: EventDefinition<{
|
|
175
|
+
key: string;
|
|
176
|
+
}>;
|
|
177
|
+
```
|
package/docs/styles.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Styles + Directives
|
|
2
|
+
|
|
3
|
+
Source: `src/styles/*.ts`, `src/directives/*.ts`
|
|
4
|
+
|
|
5
|
+
## Base Styles
|
|
6
|
+
|
|
7
|
+
Source: `src/styles/base.styles.ts`
|
|
8
|
+
|
|
9
|
+
Design tokens for borders, backgrounds, and text.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const border = {
|
|
13
|
+
default: "border-base-200 dark:border-base-700",
|
|
14
|
+
subtle: "border-base-200 dark:border-base-700",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const bg = {
|
|
18
|
+
surface: "bg-white dark:bg-base-900",
|
|
19
|
+
muted: "bg-base-100 dark:bg-base-800",
|
|
20
|
+
subtle: "bg-base-200 dark:bg-base-700",
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const text = {
|
|
24
|
+
default: "text-base-900 dark:text-base-100",
|
|
25
|
+
muted: "text-base-400 dark:text-base-500",
|
|
26
|
+
placeholder: "placeholder:text-base-400 dark:placeholder:text-base-500",
|
|
27
|
+
};
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Control Styles
|
|
31
|
+
|
|
32
|
+
Source: `src/styles/control.styles.ts`
|
|
33
|
+
|
|
34
|
+
Tokens for interactive component sizing, padding, gaps, and states.
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const state = {
|
|
38
|
+
disabled: "pointer-events-none cursor-default opacity-30",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
type ComponentSize = "xs" | "sm" | "md" | "lg" | "xl";
|
|
42
|
+
|
|
43
|
+
const pad: Record<ComponentSize | string, string> = {
|
|
44
|
+
md: "px-2 py-1",
|
|
45
|
+
xs: "px-1 py-0",
|
|
46
|
+
sm: "px-1.5 py-0.5",
|
|
47
|
+
lg: "px-3 py-2",
|
|
48
|
+
xl: "px-4 py-3",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const gap: Record<ComponentSize | string, string> = {
|
|
52
|
+
md: "gap-1",
|
|
53
|
+
xs: "gap-0",
|
|
54
|
+
sm: "gap-0.5",
|
|
55
|
+
lg: "gap-1.5",
|
|
56
|
+
xl: "gap-2",
|
|
57
|
+
};
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Theme Styles
|
|
61
|
+
|
|
62
|
+
Source: `src/styles/theme.styles.ts`
|
|
63
|
+
|
|
64
|
+
Semantic color tokens for six themes: `primary`, `info`, `success`, `warning`, `danger`, `base`.
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
type SemanticTheme = "primary" | "info" | "success" | "warning" | "danger" | "base";
|
|
68
|
+
|
|
69
|
+
const themeTokens: Record<SemanticTheme, {
|
|
70
|
+
solid: string; // solid background + white text
|
|
71
|
+
solidHover: string; // hover state for solid
|
|
72
|
+
light: string; // light background + dark text
|
|
73
|
+
text: string; // text color only
|
|
74
|
+
hoverBg: string; // hover background
|
|
75
|
+
border: string; // border color
|
|
76
|
+
}>;
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Each theme provides six variants:
|
|
80
|
+
|
|
81
|
+
| Variant | Usage |
|
|
82
|
+
|---------|-------|
|
|
83
|
+
| `solid` | Tag, Button(solid), Progress bar fill |
|
|
84
|
+
| `solidHover` | Button(solid) hover state |
|
|
85
|
+
| `light` | Alert background |
|
|
86
|
+
| `text` | Link color, Tab selected |
|
|
87
|
+
| `hoverBg` | Button(ghost) hover, List item hover |
|
|
88
|
+
| `border` | Button(outline) border |
|
|
89
|
+
|
|
90
|
+
Example values for `primary`:
|
|
91
|
+
```
|
|
92
|
+
solid: "bg-primary-500 text-white"
|
|
93
|
+
solidHover: "hover:bg-primary-600 dark:hover:bg-primary-400"
|
|
94
|
+
light: "bg-primary-100 text-primary-900 dark:bg-primary-900/40 dark:text-primary-100"
|
|
95
|
+
text: "text-primary-600 dark:text-primary-400"
|
|
96
|
+
hoverBg: "hover:bg-primary-100 dark:hover:bg-primary-800/30"
|
|
97
|
+
border: "border-primary-300 dark:border-primary-600"
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Directives
|
|
101
|
+
|
|
102
|
+
### ripple
|
|
103
|
+
|
|
104
|
+
Directive that adds a material-design-style ripple effect on pointer down.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
function ripple(el: HTMLElement, accessor: Accessor<boolean>): void;
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Usage in TSX:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
<button use:ripple={!props.disabled}>Click me</button>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Behavior:
|
|
117
|
+
- Creates an internal ripple container with `overflow: hidden`.
|
|
118
|
+
- Changes element position to `relative` if it is `static` (restored on cleanup).
|
|
119
|
+
- Single ripple mode: removes previous ripple on new click.
|
|
120
|
+
- Respects `prefers-reduced-motion: reduce`.
|
|
121
|
+
- Ripple radius based on distance from click point to farthest corner.
|
|
122
|
+
|
|
123
|
+
To use the directive, import and void it at the top of your file:
|
|
124
|
+
```tsx
|
|
125
|
+
import { ripple } from "@simplysm/solid";
|
|
126
|
+
void ripple;
|
|
127
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.98",
|
|
4
4
|
"description": "Simplysm package - SolidJS library",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -30,42 +30,35 @@
|
|
|
30
30
|
"@solid-primitives/storage": "^4.3.4",
|
|
31
31
|
"@solidjs/router": "^0.15.4",
|
|
32
32
|
"@tabler/icons-solidjs": "^3.40.0",
|
|
33
|
-
"@tiptap/core": "^3.20.
|
|
34
|
-
"@tiptap/extension-color": "^3.20.
|
|
35
|
-
"@tiptap/extension-highlight": "^3.20.
|
|
36
|
-
"@tiptap/extension-image": "^3.20.
|
|
37
|
-
"@tiptap/extension-table": "^3.20.
|
|
38
|
-
"@tiptap/extension-table-cell": "^3.20.
|
|
39
|
-
"@tiptap/extension-table-header": "^3.20.
|
|
40
|
-
"@tiptap/extension-table-row": "^3.20.
|
|
41
|
-
"@tiptap/extension-text-align": "^3.20.
|
|
42
|
-
"@tiptap/extension-text-style": "^3.20.
|
|
43
|
-
"@tiptap/pm": "^3.20.
|
|
44
|
-
"@tiptap/starter-kit": "^3.20.
|
|
33
|
+
"@tiptap/core": "^3.20.4",
|
|
34
|
+
"@tiptap/extension-color": "^3.20.4",
|
|
35
|
+
"@tiptap/extension-highlight": "^3.20.4",
|
|
36
|
+
"@tiptap/extension-image": "^3.20.4",
|
|
37
|
+
"@tiptap/extension-table": "^3.20.4",
|
|
38
|
+
"@tiptap/extension-table-cell": "^3.20.4",
|
|
39
|
+
"@tiptap/extension-table-header": "^3.20.4",
|
|
40
|
+
"@tiptap/extension-table-row": "^3.20.4",
|
|
41
|
+
"@tiptap/extension-text-align": "^3.20.4",
|
|
42
|
+
"@tiptap/extension-text-style": "^3.20.4",
|
|
43
|
+
"@tiptap/pm": "^3.20.4",
|
|
44
|
+
"@tiptap/starter-kit": "^3.20.4",
|
|
45
45
|
"bwip-js": "^4.8.0",
|
|
46
46
|
"clsx": "^2.1.1",
|
|
47
47
|
"consola": "^3.4.2",
|
|
48
|
+
"echarts": "^6.0.0",
|
|
48
49
|
"html-to-image": "^1.11.13",
|
|
49
|
-
"jspdf": "^4.2.
|
|
50
|
+
"jspdf": "^4.2.1",
|
|
50
51
|
"solid-js": "^1.9.11",
|
|
51
52
|
"solid-tiptap": "^0.8.0",
|
|
52
53
|
"tabbable": "^6.4.0",
|
|
53
54
|
"tailwind-merge": "^3.5.0",
|
|
54
55
|
"tailwindcss": "^3.4.19",
|
|
55
|
-
"@simplysm/core-browser": "13.0.
|
|
56
|
-
"@simplysm/core-common": "13.0.
|
|
57
|
-
"@simplysm/service-
|
|
58
|
-
"@simplysm/service-
|
|
56
|
+
"@simplysm/core-browser": "13.0.98",
|
|
57
|
+
"@simplysm/core-common": "13.0.98",
|
|
58
|
+
"@simplysm/service-common": "13.0.98",
|
|
59
|
+
"@simplysm/service-client": "13.0.98"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
62
|
"@solidjs/testing-library": "^0.8.10"
|
|
62
|
-
},
|
|
63
|
-
"peerDependencies": {
|
|
64
|
-
"echarts": "^6.0.0"
|
|
65
|
-
},
|
|
66
|
-
"peerDependenciesMeta": {
|
|
67
|
-
"echarts": {
|
|
68
|
-
"optional": true
|
|
69
|
-
}
|
|
70
63
|
}
|
|
71
64
|
}
|