@simplysm/solid 13.0.29 → 13.0.31
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 +10 -5
- package/dist/components/data/Pagination.d.ts +4 -5
- package/dist/components/data/Pagination.d.ts.map +1 -1
- package/dist/components/data/Pagination.js +14 -14
- package/dist/components/data/Pagination.js.map +2 -2
- package/dist/components/data/Table.js +1 -1
- package/dist/components/data/calendar/Calendar.js +1 -1
- package/dist/components/data/kanban/Kanban.d.ts +9 -9
- package/dist/components/data/kanban/Kanban.d.ts.map +1 -1
- package/dist/components/data/kanban/Kanban.js +4 -4
- package/dist/components/data/kanban/Kanban.js.map +2 -2
- package/dist/components/data/sheet/DataSheet.d.ts.map +1 -1
- package/dist/components/data/sheet/DataSheet.js +102 -107
- package/dist/components/data/sheet/DataSheet.js.map +2 -2
- package/dist/components/data/sheet/DataSheet.styles.js +1 -1
- package/dist/components/data/sheet/types.d.ts +2 -2
- package/dist/components/data/sheet/types.d.ts.map +1 -1
- package/dist/components/disclosure/Dialog.d.ts +8 -8
- package/dist/components/disclosure/Dialog.d.ts.map +1 -1
- package/dist/components/disclosure/Dialog.js +64 -69
- package/dist/components/disclosure/Dialog.js.map +2 -2
- package/dist/components/disclosure/DialogContext.d.ts +4 -4
- package/dist/components/disclosure/DialogContext.d.ts.map +1 -1
- package/dist/components/disclosure/DialogProvider.js +8 -8
- package/dist/components/disclosure/DialogProvider.js.map +2 -2
- package/dist/components/feedback/Progress.d.ts +3 -3
- package/dist/components/feedback/Progress.d.ts.map +1 -1
- package/dist/components/feedback/Progress.js +1 -1
- package/dist/components/feedback/Progress.js.map +2 -2
- package/dist/components/feedback/busy/BusyContainer.d.ts +1 -0
- package/dist/components/feedback/busy/BusyContainer.d.ts.map +1 -1
- package/dist/components/feedback/busy/BusyContainer.js +13 -6
- package/dist/components/feedback/busy/BusyContainer.js.map +2 -2
- package/dist/components/feedback/notification/NotificationBanner.js +1 -1
- package/dist/components/feedback/notification/NotificationBanner.js.map +1 -1
- package/dist/components/feedback/notification/NotificationBell.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationBell.js +4 -2
- package/dist/components/feedback/notification/NotificationBell.js.map +2 -2
- package/dist/components/feedback/notification/NotificationProvider.d.ts.map +1 -1
- package/dist/components/feedback/notification/NotificationProvider.js +1 -0
- package/dist/components/feedback/notification/NotificationProvider.js.map +1 -1
- package/dist/components/form-control/Invalid.d.ts +4 -2
- package/dist/components/form-control/Invalid.d.ts.map +1 -1
- package/dist/components/form-control/Invalid.js +81 -41
- package/dist/components/form-control/Invalid.js.map +2 -2
- package/dist/components/form-control/ThemeToggle.d.ts.map +1 -1
- package/dist/components/form-control/ThemeToggle.js +4 -5
- package/dist/components/form-control/ThemeToggle.js.map +2 -2
- package/dist/components/form-control/checkbox/Checkbox.d.ts +4 -2
- package/dist/components/form-control/checkbox/Checkbox.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Checkbox.js +65 -52
- package/dist/components/form-control/checkbox/Checkbox.js.map +2 -2
- package/dist/components/form-control/checkbox/Checkbox.styles.d.ts +1 -2
- package/dist/components/form-control/checkbox/Checkbox.styles.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Checkbox.styles.js +3 -9
- package/dist/components/form-control/checkbox/Checkbox.styles.js.map +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.d.ts +9 -9
- package/dist/components/form-control/checkbox/CheckboxGroup.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/CheckboxGroup.js +10 -82
- package/dist/components/form-control/checkbox/CheckboxGroup.js.map +2 -2
- package/dist/components/form-control/checkbox/Radio.d.ts +4 -2
- package/dist/components/form-control/checkbox/Radio.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/Radio.js +64 -51
- package/dist/components/form-control/checkbox/Radio.js.map +2 -2
- package/dist/components/form-control/checkbox/RadioGroup.d.ts +9 -9
- package/dist/components/form-control/checkbox/RadioGroup.d.ts.map +1 -1
- package/dist/components/form-control/checkbox/RadioGroup.js +10 -77
- package/dist/components/form-control/checkbox/RadioGroup.js.map +2 -2
- package/dist/components/form-control/color-picker/ColorPicker.d.ts +8 -3
- package/dist/components/form-control/color-picker/ColorPicker.d.ts.map +1 -1
- package/dist/components/form-control/color-picker/ColorPicker.js +43 -26
- package/dist/components/form-control/color-picker/ColorPicker.js.map +2 -2
- package/dist/components/form-control/combobox/Combobox.d.ts +8 -8
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/Combobox.js +72 -59
- package/dist/components/form-control/combobox/Combobox.js.map +2 -2
- package/dist/components/form-control/editor/EditorToolbar.d.ts.map +1 -1
- package/dist/components/form-control/editor/EditorToolbar.js +3 -2
- package/dist/components/form-control/editor/EditorToolbar.js.map +2 -2
- package/dist/components/form-control/field/DatePicker.d.ts +6 -0
- package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DatePicker.js +138 -117
- package/dist/components/form-control/field/DatePicker.js.map +2 -2
- package/dist/components/form-control/field/DateTimePicker.d.ts +6 -0
- package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.js +138 -115
- package/dist/components/form-control/field/DateTimePicker.js.map +2 -2
- package/dist/components/form-control/field/Field.styles.d.ts +14 -0
- package/dist/components/form-control/field/Field.styles.d.ts.map +1 -1
- package/dist/components/form-control/field/Field.styles.js +30 -0
- package/dist/components/form-control/field/Field.styles.js.map +1 -1
- package/dist/components/form-control/field/FieldPlaceholder.d.ts +7 -0
- package/dist/components/form-control/field/FieldPlaceholder.d.ts.map +1 -0
- package/dist/components/form-control/field/FieldPlaceholder.js +34 -0
- package/dist/components/form-control/field/FieldPlaceholder.js.map +6 -0
- package/dist/components/form-control/field/NumberInput.d.ts +10 -0
- package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.js +149 -115
- package/dist/components/form-control/field/NumberInput.js.map +2 -2
- package/dist/components/form-control/field/TextInput.d.ts +12 -0
- package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
- package/dist/components/form-control/field/TextInput.js +162 -116
- package/dist/components/form-control/field/TextInput.js.map +2 -2
- package/dist/components/form-control/field/Textarea.d.ts +10 -0
- package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
- package/dist/components/form-control/field/Textarea.js +156 -121
- package/dist/components/form-control/field/Textarea.js.map +2 -2
- package/dist/components/form-control/field/TimePicker.d.ts +10 -0
- package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/TimePicker.js +126 -94
- package/dist/components/form-control/field/TimePicker.js.map +2 -2
- package/dist/components/form-control/select/Select.d.ts +7 -9
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +71 -60
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
- package/dist/components/form-control/state-preset/StatePreset.js +2 -1
- package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
- package/dist/components/layout/sidebar/SidebarMenu.js +1 -1
- package/dist/components/layout/sidebar/SidebarMenu.js.map +1 -1
- package/dist/components/layout/sidebar/SidebarUser.js +2 -2
- package/dist/components/layout/sidebar/SidebarUser.js.map +1 -1
- package/dist/hooks/createItemTemplate.d.ts +17 -0
- package/dist/hooks/createItemTemplate.d.ts.map +1 -0
- package/dist/hooks/createItemTemplate.js +40 -0
- package/dist/hooks/createItemTemplate.js.map +6 -0
- package/dist/hooks/createPointerDrag.d.ts +13 -0
- package/dist/hooks/createPointerDrag.d.ts.map +1 -0
- package/dist/hooks/createPointerDrag.js +15 -0
- package/dist/hooks/createPointerDrag.js.map +6 -0
- package/dist/hooks/createSelectionGroup.d.ts +70 -0
- package/dist/hooks/createSelectionGroup.d.ts.map +1 -0
- package/dist/hooks/createSelectionGroup.js +141 -0
- package/dist/hooks/createSelectionGroup.js.map +6 -0
- package/dist/hooks/useLocalStorage.d.ts +5 -3
- package/dist/hooks/useLocalStorage.d.ts.map +1 -1
- package/dist/hooks/useLocalStorage.js.map +1 -1
- package/dist/hooks/{createPwaUpdate.d.ts → usePwaUpdate.d.ts} +2 -2
- package/dist/hooks/usePwaUpdate.d.ts.map +1 -0
- package/dist/hooks/{createPwaUpdate.js → usePwaUpdate.js} +3 -3
- package/dist/hooks/usePwaUpdate.js.map +6 -0
- package/dist/hooks/useSyncConfig.d.ts +3 -3
- package/dist/hooks/useSyncConfig.d.ts.map +1 -1
- package/dist/hooks/useSyncConfig.js +6 -7
- package/dist/hooks/useSyncConfig.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/providers/InitializeProvider.js +2 -2
- package/dist/providers/InitializeProvider.js.map +2 -2
- package/dist/providers/ThemeContext.d.ts.map +1 -1
- package/dist/providers/ThemeContext.js +2 -1
- package/dist/providers/ThemeContext.js.map +2 -2
- package/dist/styles/patterns.styles.d.ts +1 -0
- package/dist/styles/patterns.styles.d.ts.map +1 -1
- package/dist/styles/patterns.styles.js +11 -0
- package/dist/styles/patterns.styles.js.map +1 -1
- package/dist/styles/tokens.styles.d.ts +1 -0
- package/dist/styles/tokens.styles.d.ts.map +1 -1
- package/dist/styles/tokens.styles.js.map +1 -1
- package/docs/data-components.md +34 -5
- package/docs/disclosure.md +28 -8
- package/docs/feedback.md +25 -2
- package/docs/form-controls.md +289 -33
- package/docs/hooks.md +19 -7
- package/docs/layout.md +12 -0
- package/docs/providers.md +120 -8
- package/docs/styling.md +90 -0
- package/package.json +3 -3
- package/src/components/data/Pagination.tsx +20 -21
- package/src/components/data/Table.tsx +1 -1
- package/src/components/data/calendar/Calendar.tsx +1 -1
- package/src/components/data/kanban/Kanban.tsx +18 -25
- package/src/components/data/sheet/DataSheet.styles.ts +1 -1
- package/src/components/data/sheet/DataSheet.tsx +122 -131
- package/src/components/data/sheet/types.ts +2 -2
- package/src/components/disclosure/Dialog.tsx +87 -100
- package/src/components/disclosure/DialogContext.ts +4 -4
- package/src/components/disclosure/DialogProvider.tsx +4 -4
- package/src/components/feedback/Progress.tsx +9 -5
- package/src/components/feedback/busy/BusyContainer.tsx +9 -5
- package/src/components/feedback/notification/NotificationBanner.tsx +1 -1
- package/src/components/feedback/notification/NotificationBell.tsx +4 -12
- package/src/components/feedback/notification/NotificationProvider.tsx +1 -0
- package/src/components/form-control/Invalid.tsx +114 -52
- package/src/components/form-control/ThemeToggle.tsx +4 -17
- package/src/components/form-control/checkbox/Checkbox.styles.ts +2 -9
- package/src/components/form-control/checkbox/Checkbox.tsx +39 -28
- package/src/components/form-control/checkbox/CheckboxGroup.tsx +18 -97
- package/src/components/form-control/checkbox/Radio.tsx +39 -28
- package/src/components/form-control/checkbox/RadioGroup.tsx +18 -92
- package/src/components/form-control/color-picker/ColorPicker.tsx +36 -16
- package/src/components/form-control/combobox/Combobox.tsx +43 -33
- package/src/components/form-control/editor/EditorToolbar.tsx +3 -14
- package/src/components/form-control/field/DatePicker.tsx +99 -97
- package/src/components/form-control/field/DateTimePicker.tsx +107 -95
- package/src/components/form-control/field/Field.styles.ts +45 -0
- package/src/components/form-control/field/FieldPlaceholder.tsx +18 -0
- package/src/components/form-control/field/NumberInput.tsx +122 -94
- package/src/components/form-control/field/TextInput.tsx +119 -95
- package/src/components/form-control/field/Textarea.tsx +124 -98
- package/src/components/form-control/field/TimePicker.tsx +101 -75
- package/src/components/form-control/select/Select.tsx +52 -44
- package/src/components/form-control/state-preset/StatePreset.tsx +2 -8
- package/src/components/layout/sidebar/SidebarMenu.tsx +1 -1
- package/src/components/layout/sidebar/SidebarUser.tsx +3 -3
- package/src/hooks/createItemTemplate.tsx +42 -0
- package/src/hooks/createPointerDrag.ts +28 -0
- package/src/hooks/createSelectionGroup.tsx +235 -0
- package/src/hooks/useLocalStorage.ts +8 -4
- package/src/hooks/{createPwaUpdate.ts → usePwaUpdate.ts} +1 -1
- package/src/hooks/useSyncConfig.ts +9 -13
- package/src/index.ts +1 -3
- package/src/providers/InitializeProvider.tsx +2 -2
- package/src/providers/ThemeContext.tsx +2 -1
- package/src/styles/patterns.styles.ts +12 -0
- package/src/styles/tokens.styles.ts +1 -0
- package/dist/hooks/createPwaUpdate.d.ts.map +0 -1
- package/dist/hooks/createPwaUpdate.js.map +0 -6
package/docs/providers.md
CHANGED
|
@@ -2,34 +2,146 @@
|
|
|
2
2
|
|
|
3
3
|
## InitializeProvider
|
|
4
4
|
|
|
5
|
-
Root provider that wraps the entire application. Automatically sets up all required providers: configuration context, theme (dark/light/system), notification system with banner, global error capturing (window.onerror, unhandledrejection), busy overlay,
|
|
5
|
+
Root provider that wraps the entire application. Automatically sets up all required providers: configuration context, theme (dark/light/system), notification system with banner, global error capturing (window.onerror, unhandledrejection), busy overlay, programmatic dialog support, and form control clipboard value copy.
|
|
6
6
|
|
|
7
|
-
See [
|
|
7
|
+
See the [Configuration](../README.md#configuration) section in the main README for setup instructions and `AppConfig` options.
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## ServiceClientProvider
|
|
12
12
|
|
|
13
|
-
WebSocket client provider for RPC communication with `@simplysm/service-server`. Wraps `ServiceClient` from `@simplysm/service-client`.
|
|
13
|
+
WebSocket client provider for RPC communication with `@simplysm/service-server`. Wraps `ServiceClient` from `@simplysm/service-client`. Provides `useServiceClient` hook to components.
|
|
14
|
+
|
|
15
|
+
`ServiceClientProvider` takes no props. After mounting, use `useServiceClient()` to connect, close, and access client instances by key.
|
|
14
16
|
|
|
15
17
|
```tsx
|
|
16
|
-
import { ServiceClientProvider } from "@simplysm/solid";
|
|
18
|
+
import { ServiceClientProvider, useServiceClient } from "@simplysm/solid";
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
// Wrap your app
|
|
21
|
+
<ServiceClientProvider>
|
|
19
22
|
<App />
|
|
20
23
|
</ServiceClientProvider>
|
|
24
|
+
|
|
25
|
+
// In a component
|
|
26
|
+
function App() {
|
|
27
|
+
const client = useServiceClient();
|
|
28
|
+
|
|
29
|
+
onMount(async () => {
|
|
30
|
+
await client.connect("main", { host: "localhost", port: 3000, ssl: false });
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
onCleanup(async () => {
|
|
34
|
+
await client.close("main");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const handleCall = async () => {
|
|
38
|
+
const svc = client.get("main");
|
|
39
|
+
const result = await svc.call("MyService", "myMethod", [arg1, arg2]);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
21
42
|
```
|
|
22
43
|
|
|
44
|
+
**useServiceClient API:**
|
|
45
|
+
|
|
46
|
+
| Method | Signature | Description |
|
|
47
|
+
|--------|-----------|-------------|
|
|
48
|
+
| `connect` | `(key: string, options?: Partial<ServiceConnectionConfig>) => Promise<void>` | Open WebSocket connection |
|
|
49
|
+
| `close` | `(key: string) => Promise<void>` | Close connection by key |
|
|
50
|
+
| `get` | `(key: string) => ServiceClient` | Get connected client by key (throws if not connected) |
|
|
51
|
+
| `isConnected` | `(key: string) => boolean` | Check connection state |
|
|
52
|
+
|
|
53
|
+
`ServiceConnectionConfig`: `{ host: string; port: number; ssl: boolean }`
|
|
54
|
+
|
|
55
|
+
Defaults for `host`, `port`, and `ssl` are derived from `window.location` when omitted.
|
|
56
|
+
|
|
23
57
|
---
|
|
24
58
|
|
|
25
59
|
## SharedDataProvider
|
|
26
60
|
|
|
27
|
-
Shared data provider for managing server-side data subscriptions. Works with `ServiceClientProvider` to provide reactive shared data across components
|
|
61
|
+
Shared data provider for managing server-side data subscriptions. Works with `ServiceClientProvider` to provide reactive shared data across components via `useSharedData`.
|
|
28
62
|
|
|
29
63
|
```tsx
|
|
30
|
-
import { SharedDataProvider,
|
|
64
|
+
import { SharedDataProvider, type SharedDataDefinition } from "@simplysm/solid";
|
|
65
|
+
|
|
66
|
+
interface MySharedData {
|
|
67
|
+
users: UserRecord;
|
|
68
|
+
products: ProductRecord;
|
|
69
|
+
}
|
|
31
70
|
|
|
32
|
-
<
|
|
71
|
+
const definitions: { [K in keyof MySharedData]: SharedDataDefinition<MySharedData[K]> } = {
|
|
72
|
+
users: {
|
|
73
|
+
serviceKey: "main",
|
|
74
|
+
fetch: async (changeKeys) => fetchUsers(changeKeys),
|
|
75
|
+
getKey: (item) => item.id,
|
|
76
|
+
orderBy: [(item) => item.name, "asc"],
|
|
77
|
+
},
|
|
78
|
+
products: {
|
|
79
|
+
serviceKey: "main",
|
|
80
|
+
fetch: async (changeKeys) => fetchProducts(changeKeys),
|
|
81
|
+
getKey: (item) => item.id,
|
|
82
|
+
orderBy: [(item) => item.name, "asc"],
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
<SharedDataProvider definitions={definitions}>
|
|
33
87
|
<App />
|
|
34
88
|
</SharedDataProvider>
|
|
35
89
|
```
|
|
90
|
+
|
|
91
|
+
**SharedDataProvider Props:**
|
|
92
|
+
|
|
93
|
+
| Prop | Type | Description |
|
|
94
|
+
|------|------|-------------|
|
|
95
|
+
| `definitions` | `{ [K in keyof TSharedData]: SharedDataDefinition<TSharedData[K]> }` | Map of data key to fetch definition |
|
|
96
|
+
|
|
97
|
+
**SharedDataDefinition type:**
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
interface SharedDataDefinition<TData> {
|
|
101
|
+
serviceKey: string; // Connection key (matches useServiceClient key)
|
|
102
|
+
fetch: (changeKeys?: Array<string | number>) => Promise<TData[]>; // Data fetch function
|
|
103
|
+
getKey: (item: TData) => string | number; // Primary key extractor
|
|
104
|
+
orderBy: [(item: TData) => unknown, "asc" | "desc"][]; // Sort order
|
|
105
|
+
filter?: unknown; // Optional filter for change events
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**useSharedData API:**
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { useSharedData } from "@simplysm/solid";
|
|
113
|
+
|
|
114
|
+
function MyComponent() {
|
|
115
|
+
const sharedData = useSharedData<MySharedData>();
|
|
116
|
+
|
|
117
|
+
const users = () => sharedData.users.items(); // Accessor<TData[]>
|
|
118
|
+
const user = () => sharedData.users.get(userId()); // TData | undefined
|
|
119
|
+
|
|
120
|
+
const handleUpdate = async () => {
|
|
121
|
+
await sharedData.users.emit([updatedUserId]); // trigger refetch for keys
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**SharedDataAccessor API:**
|
|
127
|
+
|
|
128
|
+
| Property/Method | Type | Description |
|
|
129
|
+
|-----------------|------|-------------|
|
|
130
|
+
| `items` | `Accessor<TData[]>` | Reactive item array |
|
|
131
|
+
| `get` | `(key: string \| number \| undefined) => TData \| undefined` | Get item by key |
|
|
132
|
+
| `emit` | `(changeKeys?: Array<string \| number>) => Promise<void>` | Emit change event to server (triggers refetch in all subscribers) |
|
|
133
|
+
|
|
134
|
+
**SharedDataValue extras:**
|
|
135
|
+
|
|
136
|
+
| Property/Method | Type | Description |
|
|
137
|
+
|-----------------|------|-------------|
|
|
138
|
+
| `wait` | `() => Promise<void>` | Wait until all initial fetches complete |
|
|
139
|
+
| `busy` | `Accessor<boolean>` | True while any fetch is in progress |
|
|
140
|
+
|
|
141
|
+
**SharedDataChangeEvent:**
|
|
142
|
+
|
|
143
|
+
`SharedDataChangeEvent` is the event definition used internally by `SharedDataProvider` to communicate data changes between server and clients. Export it if you need to emit changes from the server side.
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { SharedDataChangeEvent } from "@simplysm/solid";
|
|
147
|
+
```
|
package/docs/styling.md
CHANGED
|
@@ -22,9 +22,11 @@
|
|
|
22
22
|
| `h-field` / `size-field` | Default field height (based on `py-1`) |
|
|
23
23
|
| `h-field-sm` / `size-field-sm` | Small field height (based on `py-0.5`) |
|
|
24
24
|
| `h-field-lg` / `size-field-lg` | Large field height (based on `py-2`) |
|
|
25
|
+
| `h-field-xl` / `size-field-xl` | Extra-large field height (based on `py-3`) |
|
|
25
26
|
| `h-field-inset` / `size-field-inset` | Inset field height (excludes border) |
|
|
26
27
|
| `h-field-inset-sm` / `size-field-inset-sm` | Small inset field height |
|
|
27
28
|
| `h-field-inset-lg` / `size-field-inset-lg` | Large inset field height |
|
|
29
|
+
| `h-field-inset-xl` / `size-field-inset-xl` | Extra-large inset field height |
|
|
28
30
|
|
|
29
31
|
## z-index Layers
|
|
30
32
|
|
|
@@ -65,3 +67,91 @@ const baseClass = clsx(
|
|
|
65
67
|
|
|
66
68
|
const className = twMerge(baseClass, props.class);
|
|
67
69
|
```
|
|
70
|
+
|
|
71
|
+
## Exported Style Tokens
|
|
72
|
+
|
|
73
|
+
`@simplysm/solid` exports TypeScript style constants and type definitions for use when building custom components that integrate with the library's design system.
|
|
74
|
+
|
|
75
|
+
### tokens.styles
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import {
|
|
79
|
+
type ComponentSize, // "sm" | "lg" | "xl"
|
|
80
|
+
type SemanticTheme, // "primary" | "info" | "success" | "warning" | "danger" | "base"
|
|
81
|
+
borderDefault, // Tailwind classes for default border color
|
|
82
|
+
borderSubtle, // Tailwind classes for subtle border color
|
|
83
|
+
bgSurface, // Tailwind classes for surface background
|
|
84
|
+
textDefault, // Tailwind classes for default text color
|
|
85
|
+
textMuted, // Tailwind classes for muted text color
|
|
86
|
+
textPlaceholder, // Tailwind classes for placeholder text color
|
|
87
|
+
disabledOpacity, // Tailwind classes for disabled state opacity
|
|
88
|
+
paddingSm, // Tailwind classes for small padding (px-1.5 py-0.5)
|
|
89
|
+
paddingLg, // Tailwind classes for large padding (px-3 py-2)
|
|
90
|
+
paddingXl, // Tailwind classes for extra-large padding (px-4 py-3)
|
|
91
|
+
themeTokens, // Record<SemanticTheme, { solid, solidHover, light, text, hoverBg, border }>
|
|
92
|
+
} from "@simplysm/solid";
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### patterns.styles
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
import {
|
|
99
|
+
iconButtonBase, // Base classes for icon-only buttons
|
|
100
|
+
insetFocusOutline, // Focus outline (focus-within) for inset fields
|
|
101
|
+
insetFocusOutlineSelf, // Focus outline (focus) for inset trigger elements
|
|
102
|
+
insetBase, // Base layout classes for inset mode
|
|
103
|
+
fieldSurface, // Field surface (background, border, focus ring)
|
|
104
|
+
inputBase, // Base classes for <input> elements
|
|
105
|
+
} from "@simplysm/solid";
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Field.styles
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import {
|
|
112
|
+
type FieldSize, // "sm" | "lg" | "xl"
|
|
113
|
+
getFieldWrapperClass, // Utility to build field wrapper class string
|
|
114
|
+
getTextareaWrapperClass, // Utility to build textarea wrapper class string
|
|
115
|
+
fieldInputClass, // Base classes for field <input> element
|
|
116
|
+
fieldGapClasses, // Gap classes per size (with prefix icon)
|
|
117
|
+
} from "@simplysm/solid";
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Checkbox.styles
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import {
|
|
124
|
+
type CheckboxSize, // "sm" | "lg" | "xl"
|
|
125
|
+
checkboxBaseClass, // Base wrapper classes
|
|
126
|
+
indicatorBaseClass, // Base indicator (box) classes
|
|
127
|
+
checkedClass, // Checked state classes (primary color)
|
|
128
|
+
checkboxSizeClasses, // Size variant classes
|
|
129
|
+
checkboxInsetClass, // Inset mode classes
|
|
130
|
+
checkboxInlineClass, // Inline display classes
|
|
131
|
+
checkboxDisabledClass, // Disabled state classes
|
|
132
|
+
} from "@simplysm/solid";
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### DataSheet.styles
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
import {
|
|
139
|
+
dataSheetContainerClass, tableClass, thClass, thContentClass, tdClass,
|
|
140
|
+
summaryThClass, insetContainerClass, insetTableClass, defaultContainerClass,
|
|
141
|
+
sortableThClass, sortIconClass, toolbarClass, fixedClass, fixedLastClass,
|
|
142
|
+
resizerClass, resizeIndicatorClass, featureThClass, featureTdClass,
|
|
143
|
+
expandIndentGuideClass, expandIndentGuideLineClass, expandToggleClass,
|
|
144
|
+
reorderHandleClass, reorderIndicatorClass, configButtonClass,
|
|
145
|
+
// etc.
|
|
146
|
+
} from "@simplysm/solid";
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### ListItem.styles
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import {
|
|
153
|
+
listItemBaseClass, listItemSizeClasses, listItemSelectedClass,
|
|
154
|
+
listItemDisabledClass, listItemReadonlyClass, listItemIndentGuideClass,
|
|
155
|
+
listItemContentClass, getListItemSelectedIconClass,
|
|
156
|
+
} from "@simplysm/solid";
|
|
157
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/solid",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.31",
|
|
4
4
|
"description": "심플리즘 패키지 - SolidJS 라이브러리",
|
|
5
5
|
"author": "김석래",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"solid-tiptap": "^0.8.0",
|
|
50
50
|
"tailwind-merge": "^3.4.1",
|
|
51
51
|
"tailwindcss": "^3.4.19",
|
|
52
|
-
"@simplysm/core-browser": "13.0.
|
|
53
|
-
"@simplysm/core-common": "13.0.
|
|
52
|
+
"@simplysm/core-browser": "13.0.31",
|
|
53
|
+
"@simplysm/core-common": "13.0.31"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@solidjs/testing-library": "^0.8.10"
|
|
@@ -9,22 +9,21 @@ import {
|
|
|
9
9
|
} from "@tabler/icons-solidjs";
|
|
10
10
|
import { Button } from "../form-control/Button";
|
|
11
11
|
import { Icon } from "../display/Icon";
|
|
12
|
-
|
|
13
|
-
type PaginationSize = "sm" | "lg";
|
|
12
|
+
import { type ComponentSizeCompact } from "../../styles/tokens.styles";
|
|
14
13
|
|
|
15
14
|
export interface PaginationProps extends JSX.HTMLAttributes<HTMLElement> {
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
page: number;
|
|
16
|
+
onPageChange?: (page: number) => void;
|
|
18
17
|
totalPageCount: number;
|
|
19
18
|
displayPageCount?: number;
|
|
20
|
-
size?:
|
|
19
|
+
size?: ComponentSizeCompact;
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
const baseClass = clsx("inline-flex items-center");
|
|
24
23
|
|
|
25
24
|
const btnClass = clsx("border-none font-normal");
|
|
26
25
|
|
|
27
|
-
const gapClasses: Record<
|
|
26
|
+
const gapClasses: Record<ComponentSizeCompact | "default", string> = {
|
|
28
27
|
default: "gap-1",
|
|
29
28
|
sm: "gap-0.5",
|
|
30
29
|
lg: "gap-1.5",
|
|
@@ -33,8 +32,8 @@ const gapClasses: Record<PaginationSize | "default", string> = {
|
|
|
33
32
|
export const Pagination: Component<PaginationProps> = (props) => {
|
|
34
33
|
const [local, rest] = splitProps(props, [
|
|
35
34
|
"class",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
35
|
+
"page",
|
|
36
|
+
"onPageChange",
|
|
38
37
|
"totalPageCount",
|
|
39
38
|
"displayPageCount",
|
|
40
39
|
"size",
|
|
@@ -43,17 +42,17 @@ export const Pagination: Component<PaginationProps> = (props) => {
|
|
|
43
42
|
const visibleCount = () => local.displayPageCount ?? 10;
|
|
44
43
|
|
|
45
44
|
const pages = () => {
|
|
46
|
-
const from = Math.floor(local.
|
|
47
|
-
const to = Math.min(from + visibleCount(), local.totalPageCount);
|
|
45
|
+
const from = Math.floor((local.page - 1) / visibleCount()) * visibleCount() + 1;
|
|
46
|
+
const to = Math.min(from + visibleCount() - 1, local.totalPageCount);
|
|
48
47
|
const result: number[] = [];
|
|
49
|
-
for (let i = from; i
|
|
48
|
+
for (let i = from; i <= to; i++) {
|
|
50
49
|
result.push(i);
|
|
51
50
|
}
|
|
52
51
|
return result;
|
|
53
52
|
};
|
|
54
53
|
|
|
55
|
-
const hasPrev = () => (pages()[0] ??
|
|
56
|
-
const hasNext = () => (pages()[pages().length - 1] ??
|
|
54
|
+
const hasPrev = () => (pages()[0] ?? 1) > 1;
|
|
55
|
+
const hasNext = () => (pages()[pages().length - 1] ?? 1) < local.totalPageCount;
|
|
57
56
|
|
|
58
57
|
const getClassName = () => twMerge(baseClass, gapClasses[local.size ?? "default"], local.class);
|
|
59
58
|
|
|
@@ -65,7 +64,7 @@ export const Pagination: Component<PaginationProps> = (props) => {
|
|
|
65
64
|
variant="ghost"
|
|
66
65
|
size={local.size}
|
|
67
66
|
disabled={!hasPrev()}
|
|
68
|
-
onClick={() => local.
|
|
67
|
+
onClick={() => local.onPageChange?.(1)}
|
|
69
68
|
>
|
|
70
69
|
<Icon icon={IconChevronsLeft} size="1em" />
|
|
71
70
|
</Button>
|
|
@@ -75,7 +74,7 @@ export const Pagination: Component<PaginationProps> = (props) => {
|
|
|
75
74
|
variant="ghost"
|
|
76
75
|
size={local.size}
|
|
77
76
|
disabled={!hasPrev()}
|
|
78
|
-
onClick={() => local.
|
|
77
|
+
onClick={() => local.onPageChange?.((pages()[0] ?? 2) - 1)}
|
|
79
78
|
>
|
|
80
79
|
<Icon icon={IconChevronLeft} size="1em" />
|
|
81
80
|
</Button>
|
|
@@ -83,12 +82,12 @@ export const Pagination: Component<PaginationProps> = (props) => {
|
|
|
83
82
|
{(p) => (
|
|
84
83
|
<Button
|
|
85
84
|
class={btnClass}
|
|
86
|
-
theme={p === local.
|
|
87
|
-
variant={p === local.
|
|
85
|
+
theme={p === local.page ? "primary" : "base"}
|
|
86
|
+
variant={p === local.page ? "solid" : "ghost"}
|
|
88
87
|
size={local.size}
|
|
89
|
-
onClick={() => local.
|
|
88
|
+
onClick={() => local.onPageChange?.(p)}
|
|
90
89
|
>
|
|
91
|
-
{p
|
|
90
|
+
{p}
|
|
92
91
|
</Button>
|
|
93
92
|
)}
|
|
94
93
|
</For>
|
|
@@ -98,7 +97,7 @@ export const Pagination: Component<PaginationProps> = (props) => {
|
|
|
98
97
|
variant="ghost"
|
|
99
98
|
size={local.size}
|
|
100
99
|
disabled={!hasNext()}
|
|
101
|
-
onClick={() => local.
|
|
100
|
+
onClick={() => local.onPageChange?.((pages()[pages().length - 1] ?? 0) + 1)}
|
|
102
101
|
>
|
|
103
102
|
<Icon icon={IconChevronRight} size="1em" />
|
|
104
103
|
</Button>
|
|
@@ -108,7 +107,7 @@ export const Pagination: Component<PaginationProps> = (props) => {
|
|
|
108
107
|
variant="ghost"
|
|
109
108
|
size={local.size}
|
|
110
109
|
disabled={!hasNext()}
|
|
111
|
-
onClick={() => local.
|
|
110
|
+
onClick={() => local.onPageChange?.(local.totalPageCount)}
|
|
112
111
|
>
|
|
113
112
|
<Icon icon={IconChevronsRight} size="1em" />
|
|
114
113
|
</Button>
|
|
@@ -15,7 +15,7 @@ const baseClass = clsx(
|
|
|
15
15
|
// th
|
|
16
16
|
"[&_th]:border-l [&_th]:border-t [&_th]:border-base-300 [&_th]:dark:border-base-600",
|
|
17
17
|
"[&_th]:px-2 [&_th]:py-1",
|
|
18
|
-
"[&_th]:bg-base-100 [&_th]:text-left [&_th]:font-
|
|
18
|
+
"[&_th]:bg-base-100 [&_th]:text-left [&_th]:font-bold",
|
|
19
19
|
"[&_th]:dark:bg-base-800",
|
|
20
20
|
// td
|
|
21
21
|
"[&_td]:border-l [&_td]:border-t [&_td]:border-base-300 [&_td]:dark:border-base-600",
|
|
@@ -28,7 +28,7 @@ const baseClass = clsx(
|
|
|
28
28
|
// th
|
|
29
29
|
"[&_th]:border-l [&_th]:border-t [&_th]:border-base-300 [&_th]:dark:border-base-600",
|
|
30
30
|
"[&_th]:px-2 [&_th]:py-1",
|
|
31
|
-
"[&_th]:bg-base-100 [&_th]:text-center [&_th]:text-sm [&_th]:font-
|
|
31
|
+
"[&_th]:bg-base-100 [&_th]:text-center [&_th]:text-sm [&_th]:font-bold",
|
|
32
32
|
"[&_th]:dark:bg-base-800",
|
|
33
33
|
// td
|
|
34
34
|
"[&_td]:border-l [&_td]:border-t [&_td]:border-base-300 [&_td]:dark:border-base-600",
|
|
@@ -20,6 +20,7 @@ import { BusyContainer } from "../../feedback/busy/BusyContainer";
|
|
|
20
20
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
21
21
|
import { splitSlots } from "../../../helpers/splitSlots";
|
|
22
22
|
import "./Kanban.css";
|
|
23
|
+
import { iconButtonBase } from "../../../styles/patterns.styles";
|
|
23
24
|
import {
|
|
24
25
|
KanbanContext,
|
|
25
26
|
KanbanLaneContext,
|
|
@@ -46,11 +47,11 @@ const KanbanLaneTools: ParentComponent = (props) => (
|
|
|
46
47
|
|
|
47
48
|
// ─── KanbanCard ──────────────────────────────────────────────────
|
|
48
49
|
|
|
49
|
-
export interface KanbanCardProps extends Omit<
|
|
50
|
+
export interface KanbanCardProps<TCardValue = unknown> extends Omit<
|
|
50
51
|
JSX.HTMLAttributes<HTMLDivElement>,
|
|
51
52
|
"children" | "draggable"
|
|
52
53
|
> {
|
|
53
|
-
value?:
|
|
54
|
+
value?: TCardValue;
|
|
54
55
|
draggable?: boolean;
|
|
55
56
|
selectable?: boolean;
|
|
56
57
|
contentClass?: string;
|
|
@@ -225,8 +226,11 @@ const KanbanCard: ParentComponent<KanbanCardProps> = (props) => {
|
|
|
225
226
|
|
|
226
227
|
// ─── KanbanLane ──────────────────────────────────────────────────
|
|
227
228
|
|
|
228
|
-
export interface KanbanLaneProps extends Omit<
|
|
229
|
-
|
|
229
|
+
export interface KanbanLaneProps<TLaneValue = unknown> extends Omit<
|
|
230
|
+
JSX.HTMLAttributes<HTMLDivElement>,
|
|
231
|
+
"children"
|
|
232
|
+
> {
|
|
233
|
+
value?: TLaneValue;
|
|
230
234
|
busy?: boolean;
|
|
231
235
|
collapsible?: boolean;
|
|
232
236
|
collapsed?: boolean;
|
|
@@ -248,20 +252,12 @@ const laneDragOverClass = clsx("bg-primary-50 dark:bg-primary-950");
|
|
|
248
252
|
const laneHeaderBaseClass = clsx(
|
|
249
253
|
"flex items-center gap-2",
|
|
250
254
|
"px-3 py-2",
|
|
251
|
-
"font-
|
|
255
|
+
"font-bold",
|
|
252
256
|
"text-base-700 dark:text-base-200",
|
|
253
257
|
"select-none",
|
|
254
258
|
);
|
|
255
259
|
|
|
256
|
-
const collapseButtonClass =
|
|
257
|
-
"flex items-center justify-center",
|
|
258
|
-
"size-6 rounded",
|
|
259
|
-
"text-base-500",
|
|
260
|
-
"hover:bg-base-200 hover:text-primary-500",
|
|
261
|
-
"dark:hover:bg-base-800",
|
|
262
|
-
"transition-colors duration-150",
|
|
263
|
-
"cursor-pointer",
|
|
264
|
-
);
|
|
260
|
+
const collapseButtonClass = twMerge(iconButtonBase, "size-6", "hover:text-primary-500");
|
|
265
261
|
|
|
266
262
|
const laneToolsClass = clsx("flex items-center", "gap-1");
|
|
267
263
|
|
|
@@ -462,12 +458,7 @@ const KanbanLane: ParentComponent<KanbanLaneProps> = (props) => {
|
|
|
462
458
|
</button>
|
|
463
459
|
</Show>
|
|
464
460
|
<Show when={hasSelectableCards()}>
|
|
465
|
-
<Checkbox
|
|
466
|
-
value={isAllSelected()}
|
|
467
|
-
onValueChange={handleSelectAll}
|
|
468
|
-
inline
|
|
469
|
-
theme="primary"
|
|
470
|
-
/>
|
|
461
|
+
<Checkbox value={isAllSelected()} onValueChange={handleSelectAll} inline />
|
|
471
462
|
</Show>
|
|
472
463
|
<div class="flex-1">{slots().kanbanLaneTitle}</div>
|
|
473
464
|
<Show when={slots().kanbanLaneTools.length > 0}>
|
|
@@ -494,20 +485,22 @@ const KanbanLane: ParentComponent<KanbanLaneProps> = (props) => {
|
|
|
494
485
|
|
|
495
486
|
// ─── Kanban (Board) ──────────────────────────────────────────────
|
|
496
487
|
|
|
497
|
-
export interface KanbanProps extends Omit<
|
|
488
|
+
export interface KanbanProps<TCardValue = unknown, TLaneValue = unknown> extends Omit<
|
|
498
489
|
JSX.HTMLAttributes<HTMLDivElement>,
|
|
499
490
|
"children" | "onDrop"
|
|
500
491
|
> {
|
|
501
|
-
onDrop?: (info: KanbanDropInfo) => void;
|
|
502
|
-
selectedValues?:
|
|
503
|
-
onSelectedValuesChange?: (values:
|
|
492
|
+
onDrop?: (info: KanbanDropInfo<TLaneValue, TCardValue>) => void;
|
|
493
|
+
selectedValues?: TCardValue[];
|
|
494
|
+
onSelectedValuesChange?: (values: TCardValue[]) => void;
|
|
504
495
|
children?: JSX.Element;
|
|
505
496
|
}
|
|
506
497
|
|
|
507
498
|
const boardBaseClass = clsx("inline-flex flex-nowrap", "h-full", "gap-4");
|
|
508
499
|
|
|
509
500
|
interface KanbanComponent {
|
|
510
|
-
|
|
501
|
+
<TCardValue = unknown, TLaneValue = unknown>(
|
|
502
|
+
props: KanbanProps<TCardValue, TLaneValue>,
|
|
503
|
+
): JSX.Element;
|
|
511
504
|
Lane: typeof KanbanLane;
|
|
512
505
|
Card: typeof KanbanCard;
|
|
513
506
|
LaneTitle: typeof KanbanLaneTitle;
|