@simplysm/solid 13.0.85 → 13.0.88
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 +143 -28
- package/dist/components/data/list/ListItem.d.ts.map +1 -1
- package/dist/components/data/list/ListItem.js +11 -4
- package/dist/components/data/list/ListItem.js.map +2 -2
- package/dist/components/data/list/ListItem.styles.d.ts +2 -0
- package/dist/components/data/list/ListItem.styles.d.ts.map +1 -1
- package/dist/components/data/list/ListItem.styles.js +11 -1
- package/dist/components/data/list/ListItem.styles.js.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheet.d.ts.map +1 -1
- package/dist/components/features/crud-sheet/CrudSheet.js +7 -0
- package/dist/components/features/crud-sheet/CrudSheet.js.map +2 -2
- package/dist/components/features/data-select-button/DataSelectButton.d.ts.map +1 -1
- package/dist/components/features/data-select-button/DataSelectButton.js +30 -26
- package/dist/components/features/data-select-button/DataSelectButton.js.map +2 -2
- package/dist/components/features/permission-table/PermissionTable.js +5 -1
- package/dist/components/features/permission-table/PermissionTable.js.map +2 -2
- package/dist/components/form-control/DropdownTrigger.styles.js +1 -1
- package/dist/components/form-control/combobox/Combobox.d.ts +19 -5
- package/dist/components/form-control/combobox/Combobox.d.ts.map +1 -1
- package/dist/components/form-control/combobox/Combobox.js +2 -4
- package/dist/components/form-control/combobox/Combobox.js.map +1 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts +2 -2
- package/dist/components/form-control/date-range-picker/DateRangePicker.d.ts.map +1 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.js +10 -1
- package/dist/components/form-control/date-range-picker/DateRangePicker.js.map +2 -2
- package/dist/components/form-control/editor/RichTextEditor.d.ts +2 -2
- package/dist/components/form-control/editor/RichTextEditor.d.ts.map +1 -1
- package/dist/components/form-control/editor/RichTextEditor.js +2 -2
- package/dist/components/form-control/editor/RichTextEditor.js.map +1 -1
- package/dist/components/form-control/field/DatePicker.d.ts +2 -2
- package/dist/components/form-control/field/DatePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DatePicker.js.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.d.ts +2 -2
- package/dist/components/form-control/field/DateTimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/DateTimePicker.js.map +1 -1
- package/dist/components/form-control/field/Field.styles.d.ts +6 -7
- package/dist/components/form-control/field/Field.styles.d.ts.map +1 -1
- package/dist/components/form-control/field/Field.styles.js.map +1 -1
- package/dist/components/form-control/field/NumberInput.d.ts +2 -2
- package/dist/components/form-control/field/NumberInput.d.ts.map +1 -1
- package/dist/components/form-control/field/NumberInput.js.map +1 -1
- package/dist/components/form-control/field/TextInput.d.ts +2 -2
- package/dist/components/form-control/field/TextInput.d.ts.map +1 -1
- package/dist/components/form-control/field/TextInput.js.map +1 -1
- package/dist/components/form-control/field/Textarea.d.ts +2 -2
- package/dist/components/form-control/field/Textarea.d.ts.map +1 -1
- package/dist/components/form-control/field/Textarea.js.map +1 -1
- package/dist/components/form-control/field/TimePicker.d.ts +2 -2
- package/dist/components/form-control/field/TimePicker.d.ts.map +1 -1
- package/dist/components/form-control/field/TimePicker.js.map +1 -1
- package/dist/components/form-control/numpad/Numpad.d.ts.map +1 -1
- package/dist/components/form-control/numpad/Numpad.js +4 -17
- package/dist/components/form-control/numpad/Numpad.js.map +2 -2
- package/dist/components/form-control/select/Select.d.ts.map +1 -1
- package/dist/components/form-control/select/Select.js +19 -6
- package/dist/components/form-control/select/Select.js.map +2 -2
- package/dist/components/form-control/state-preset/StatePreset.d.ts +1 -3
- package/dist/components/form-control/state-preset/StatePreset.d.ts.map +1 -1
- package/dist/components/form-control/state-preset/StatePreset.js +69 -91
- package/dist/components/form-control/state-preset/StatePreset.js.map +2 -2
- package/dist/components/layout/FormGroup.js +1 -1
- package/dist/components/layout/FormGroup.js.map +1 -1
- package/dist/components/layout/FormTable.js +3 -3
- package/dist/components/layout/FormTable.js.map +1 -1
- package/dist/components/layout/sidebar/Sidebar.d.ts.map +1 -1
- package/dist/components/layout/sidebar/Sidebar.js +3 -6
- package/dist/components/layout/sidebar/Sidebar.js.map +2 -2
- package/dist/providers/i18n/locales/en.d.ts +2 -3
- package/dist/providers/i18n/locales/en.d.ts.map +1 -1
- package/dist/providers/i18n/locales/en.js +3 -4
- package/dist/providers/i18n/locales/en.js.map +1 -1
- package/dist/providers/i18n/locales/ko.d.ts +2 -3
- package/dist/providers/i18n/locales/ko.d.ts.map +1 -1
- package/dist/providers/i18n/locales/ko.js +3 -4
- package/dist/providers/i18n/locales/ko.js.map +1 -1
- package/docs/display-feedback.md +279 -0
- package/docs/features.md +357 -213
- package/docs/form-controls.md +261 -403
- package/docs/layout-data.md +386 -0
- package/docs/providers-hooks.md +411 -0
- package/package.json +5 -5
- package/src/components/data/list/ListItem.styles.ts +14 -2
- package/src/components/data/list/ListItem.tsx +13 -4
- package/src/components/features/crud-sheet/CrudSheet.tsx +8 -0
- package/src/components/features/data-select-button/DataSelectButton.tsx +39 -32
- package/src/components/features/permission-table/PermissionTable.tsx +1 -1
- package/src/components/form-control/DropdownTrigger.styles.ts +1 -1
- package/src/components/form-control/combobox/Combobox.tsx +42 -16
- package/src/components/form-control/date-range-picker/DateRangePicker.tsx +6 -4
- package/src/components/form-control/editor/RichTextEditor.tsx +5 -6
- package/src/components/form-control/field/DatePicker.tsx +3 -2
- package/src/components/form-control/field/DateTimePicker.tsx +3 -2
- package/src/components/form-control/field/Field.styles.ts +6 -8
- package/src/components/form-control/field/NumberInput.tsx +3 -2
- package/src/components/form-control/field/TextInput.tsx +3 -2
- package/src/components/form-control/field/Textarea.tsx +3 -2
- package/src/components/form-control/field/TimePicker.tsx +3 -2
- package/src/components/form-control/numpad/Numpad.tsx +16 -18
- package/src/components/form-control/select/Select.tsx +19 -5
- package/src/components/form-control/state-preset/StatePreset.tsx +32 -57
- package/src/components/layout/FormGroup.tsx +1 -1
- package/src/components/layout/FormTable.tsx +3 -3
- package/src/components/layout/sidebar/Sidebar.tsx +2 -3
- package/src/providers/i18n/locales/en.ts +2 -3
- package/src/providers/i18n/locales/ko.ts +2 -3
- package/tests/components/features/data-select-button/DataSelectButton.spec.tsx +62 -7
- package/tests/components/form-control/combobox/Combobox.spec.tsx +3 -3
- package/tests/components/form-control/date-range-picker/DateRangePicker.spec.tsx +56 -0
- package/docs/data.md +0 -204
- package/docs/disclosure.md +0 -146
- package/docs/display.md +0 -125
- package/docs/feedback.md +0 -156
- package/docs/helpers.md +0 -173
- package/docs/hooks.md +0 -146
- package/docs/layout.md +0 -94
- package/docs/providers.md +0 -180
|
@@ -137,7 +137,9 @@ const ComboboxItem: ParentComponent<ComboboxItemProps> = <TValue,>(
|
|
|
137
137
|
//#endregion
|
|
138
138
|
|
|
139
139
|
// Props definition
|
|
140
|
-
|
|
140
|
+
|
|
141
|
+
/** Base props shared by all Combobox variants */
|
|
142
|
+
interface ComboboxBaseProps<TValue> {
|
|
141
143
|
/** Currently selected value */
|
|
142
144
|
value?: TValue;
|
|
143
145
|
|
|
@@ -150,12 +152,6 @@ export interface ComboboxProps<TValue = unknown> {
|
|
|
150
152
|
/** Debounce delay (default: 300ms) */
|
|
151
153
|
debounceMs?: number;
|
|
152
154
|
|
|
153
|
-
/** Allow custom values */
|
|
154
|
-
allowsCustomValue?: boolean;
|
|
155
|
-
|
|
156
|
-
/** Custom value parsing function */
|
|
157
|
-
parseCustomValue?: (text: string) => TValue;
|
|
158
|
-
|
|
159
155
|
/** Function to render selected value (required) */
|
|
160
156
|
renderValue: (value: TValue) => JSX.Element;
|
|
161
157
|
|
|
@@ -190,6 +186,29 @@ export interface ComboboxProps<TValue = unknown> {
|
|
|
190
186
|
children?: JSX.Element;
|
|
191
187
|
}
|
|
192
188
|
|
|
189
|
+
/** Custom value with parser: TValue can be anything */
|
|
190
|
+
interface ComboboxCustomParserProps<TValue> extends ComboboxBaseProps<TValue> {
|
|
191
|
+
allowsCustomValue: true;
|
|
192
|
+
parseCustomValue: (text: string) => TValue;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** Custom value without parser: TValue MUST be string */
|
|
196
|
+
interface ComboboxCustomStringProps extends ComboboxBaseProps<string> {
|
|
197
|
+
allowsCustomValue: true;
|
|
198
|
+
parseCustomValue?: undefined;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/** No custom value (default) */
|
|
202
|
+
interface ComboboxDefaultProps<TValue> extends ComboboxBaseProps<TValue> {
|
|
203
|
+
allowsCustomValue?: false;
|
|
204
|
+
parseCustomValue?: undefined;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export type ComboboxProps<TValue = unknown> =
|
|
208
|
+
| ComboboxCustomParserProps<TValue>
|
|
209
|
+
| ComboboxCustomStringProps
|
|
210
|
+
| ComboboxDefaultProps<TValue>;
|
|
211
|
+
|
|
193
212
|
/**
|
|
194
213
|
* Combobox component
|
|
195
214
|
*
|
|
@@ -220,8 +239,15 @@ export interface ComboboxProps<TValue = unknown> {
|
|
|
220
239
|
* </Combobox>
|
|
221
240
|
* ```
|
|
222
241
|
*/
|
|
242
|
+
/** Internal props used after splitProps — collapses the discriminated union for runtime use */
|
|
243
|
+
interface ComboboxInternalProps<TValue> extends ComboboxBaseProps<TValue> {
|
|
244
|
+
allowsCustomValue?: boolean;
|
|
245
|
+
parseCustomValue?: (text: string) => TValue;
|
|
246
|
+
children?: JSX.Element;
|
|
247
|
+
}
|
|
248
|
+
|
|
223
249
|
const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
224
|
-
const [local, rest] = splitProps(props as
|
|
250
|
+
const [local, rest] = splitProps(props as ComboboxInternalProps<TValue>, [
|
|
225
251
|
"children",
|
|
226
252
|
"class",
|
|
227
253
|
"style",
|
|
@@ -252,8 +278,8 @@ const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
|
252
278
|
// Selected value management (controlled/uncontrolled pattern)
|
|
253
279
|
const [getValue, setInternalValue] = createControllableSignal<TValue | undefined>({
|
|
254
280
|
value: () => local.value,
|
|
255
|
-
onChange: () => local.onValueChange,
|
|
256
|
-
}
|
|
281
|
+
onChange: () => local.onValueChange as ((value: TValue | undefined) => void) | undefined,
|
|
282
|
+
});
|
|
257
283
|
|
|
258
284
|
// Debounce queue (created once on mount, debounceMs only used as initial value)
|
|
259
285
|
const debounceQueue = new DebounceQueue(local.debounceMs ?? 300);
|
|
@@ -270,7 +296,7 @@ const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
|
270
296
|
|
|
271
297
|
// Select value
|
|
272
298
|
const selectValue = (value: TValue) => {
|
|
273
|
-
setInternalValue(value
|
|
299
|
+
setInternalValue(value);
|
|
274
300
|
setQuery("");
|
|
275
301
|
setOpen(false);
|
|
276
302
|
};
|
|
@@ -346,9 +372,8 @@ const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
|
346
372
|
if (local.parseCustomValue) {
|
|
347
373
|
selectValue(local.parseCustomValue(query()));
|
|
348
374
|
} else {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
setOpen(false);
|
|
375
|
+
// TValue is string when parseCustomValue is not provided (enforced by type system)
|
|
376
|
+
selectValue(query() as TValue);
|
|
352
377
|
}
|
|
353
378
|
}
|
|
354
379
|
};
|
|
@@ -391,6 +416,7 @@ const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
|
391
416
|
class={clsx("min-w-0 flex-1 bg-transparent outline-none", text.placeholder)}
|
|
392
417
|
value={query()}
|
|
393
418
|
placeholder={currentValue === undefined ? local.placeholder : undefined}
|
|
419
|
+
|
|
394
420
|
disabled={local.disabled}
|
|
395
421
|
autocomplete="one-time-code"
|
|
396
422
|
onInput={handleInput}
|
|
@@ -399,7 +425,7 @@ const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
|
399
425
|
}
|
|
400
426
|
|
|
401
427
|
// Show value if selected and dropdown is closed
|
|
402
|
-
return <div class="
|
|
428
|
+
return <div class="whitespace-nowrap">{local.renderValue(currentValue)}</div>;
|
|
403
429
|
};
|
|
404
430
|
|
|
405
431
|
// Render items
|
|
@@ -454,7 +480,7 @@ const ComboboxInner = <TValue,>(props: ComboboxProps<TValue>) => {
|
|
|
454
480
|
style={local.style}
|
|
455
481
|
onKeyDown={handleTriggerKeyDown}
|
|
456
482
|
>
|
|
457
|
-
<div class="flex-1
|
|
483
|
+
<div class="flex-1 whitespace-nowrap">{renderDisplayContent()}</div>
|
|
458
484
|
<div class={chevronWrapperClass}>
|
|
459
485
|
<Show
|
|
460
486
|
when={busyCount() > 0}
|
|
@@ -3,9 +3,8 @@ import clsx from "clsx";
|
|
|
3
3
|
import { twMerge } from "tailwind-merge";
|
|
4
4
|
import { DateOnly } from "@simplysm/core-common";
|
|
5
5
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
6
|
-
import { type FieldSize } from "../field/Field.styles";
|
|
7
6
|
import { text } from "../../../styles/base.styles";
|
|
8
|
-
import { gap } from "../../../styles/control.styles";
|
|
7
|
+
import { type ComponentSize, gap } from "../../../styles/control.styles";
|
|
9
8
|
import { DatePicker } from "../field/DatePicker";
|
|
10
9
|
import { Select } from "../select/Select";
|
|
11
10
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
@@ -38,7 +37,7 @@ export interface DateRangePickerProps {
|
|
|
38
37
|
disabled?: boolean;
|
|
39
38
|
|
|
40
39
|
/** Size */
|
|
41
|
-
size?:
|
|
40
|
+
size?: ComponentSize;
|
|
42
41
|
|
|
43
42
|
/** Custom class */
|
|
44
43
|
class?: string;
|
|
@@ -169,7 +168,7 @@ export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
|
169
168
|
required
|
|
170
169
|
disabled={local.disabled}
|
|
171
170
|
size={local.size}
|
|
172
|
-
|
|
171
|
+
class="min-w-0"
|
|
173
172
|
>
|
|
174
173
|
<Select.Item value={"day" as DateRangePeriodType}>
|
|
175
174
|
{i18n.t("dateRangePicker.day")}
|
|
@@ -189,6 +188,7 @@ export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
|
189
188
|
unit={periodType() === "month" ? "month" : "date"}
|
|
190
189
|
value={from()}
|
|
191
190
|
onValueChange={handleFromChange}
|
|
191
|
+
required={local.required}
|
|
192
192
|
disabled={local.disabled}
|
|
193
193
|
size={local.size}
|
|
194
194
|
/>
|
|
@@ -198,6 +198,7 @@ export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
|
198
198
|
unit="date"
|
|
199
199
|
value={from()}
|
|
200
200
|
onValueChange={handleFromChange}
|
|
201
|
+
required={local.required}
|
|
201
202
|
disabled={local.disabled}
|
|
202
203
|
size={local.size}
|
|
203
204
|
/>
|
|
@@ -207,6 +208,7 @@ export const DateRangePicker: Component<DateRangePickerProps> = (props) => {
|
|
|
207
208
|
value={to()}
|
|
208
209
|
onValueChange={handleToChange}
|
|
209
210
|
min={from()}
|
|
211
|
+
required={local.required}
|
|
210
212
|
disabled={local.disabled}
|
|
211
213
|
size={local.size}
|
|
212
214
|
/>
|
|
@@ -23,9 +23,8 @@ import TableHeader from "@tiptap/extension-table-header";
|
|
|
23
23
|
import TableCell from "@tiptap/extension-table-cell";
|
|
24
24
|
import Image from "@tiptap/extension-image";
|
|
25
25
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
26
|
-
import type { FieldSize } from "../field/Field.styles";
|
|
27
26
|
import { bg, border, text } from "../../../styles/base.styles";
|
|
28
|
-
import { pad } from "../../../styles/control.styles";
|
|
27
|
+
import { type ComponentSize, pad } from "../../../styles/control.styles";
|
|
29
28
|
import { EditorToolbar } from "./EditorToolbar";
|
|
30
29
|
|
|
31
30
|
export interface RichTextEditorProps {
|
|
@@ -39,7 +38,7 @@ export interface RichTextEditorProps {
|
|
|
39
38
|
disabled?: boolean;
|
|
40
39
|
|
|
41
40
|
/** Size */
|
|
42
|
-
size?:
|
|
41
|
+
size?: ComponentSize;
|
|
43
42
|
|
|
44
43
|
/** Custom class */
|
|
45
44
|
class?: string;
|
|
@@ -49,7 +48,7 @@ export interface RichTextEditorProps {
|
|
|
49
48
|
}
|
|
50
49
|
|
|
51
50
|
// Editor content size-based style
|
|
52
|
-
const editorContentSizeClasses: Record<
|
|
51
|
+
const editorContentSizeClasses: Record<ComponentSize, string> = {
|
|
53
52
|
md: clsx(pad.xl, "min-h-32"),
|
|
54
53
|
xs: clsx(pad.xs, "min-h-12"),
|
|
55
54
|
sm: clsx(pad.sm, "min-h-24"),
|
|
@@ -151,7 +150,7 @@ export const RichTextEditor: Component<RichTextEditorProps> = (props) => {
|
|
|
151
150
|
{...rest}
|
|
152
151
|
data-rich-text-editor
|
|
153
152
|
class={twMerge(
|
|
154
|
-
clsx("flex flex-col
|
|
153
|
+
clsx("flex flex-col", text.default, "border", border.default, "rounded focus-within:border-primary-500"),
|
|
155
154
|
local.disabled && clsx(bg.muted, text.muted),
|
|
156
155
|
local.class,
|
|
157
156
|
)}
|
|
@@ -164,7 +163,7 @@ export const RichTextEditor: Component<RichTextEditorProps> = (props) => {
|
|
|
164
163
|
</Show>
|
|
165
164
|
)}
|
|
166
165
|
</Show>
|
|
167
|
-
<div ref={editorRef} class={twMerge("outline-none prose prose-sm max-w-none dark:prose-invert", editorContentSizeClasses[local.size ?? "md"])} />
|
|
166
|
+
<div ref={editorRef} class={twMerge("outline-none prose prose-sm max-w-none dark:prose-invert bg-primary-50 dark:bg-primary-950/30", editorContentSizeClasses[local.size ?? "md"])} />
|
|
168
167
|
</div>
|
|
169
168
|
);
|
|
170
169
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type Component, createMemo, type JSX, splitProps } from "solid-js";
|
|
2
2
|
import { DateOnly } from "@simplysm/core-common";
|
|
3
3
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
4
|
-
import { fieldInputClass,
|
|
4
|
+
import { fieldInputClass, getFieldWrapperClass } from "./Field.styles";
|
|
5
|
+
import type { ComponentSize } from "../../../styles/control.styles";
|
|
5
6
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
6
7
|
import { FieldShell } from "./FieldShell";
|
|
7
8
|
|
|
@@ -33,7 +34,7 @@ export interface DatePickerProps {
|
|
|
33
34
|
readOnly?: boolean;
|
|
34
35
|
|
|
35
36
|
/** Size */
|
|
36
|
-
size?:
|
|
37
|
+
size?: ComponentSize;
|
|
37
38
|
|
|
38
39
|
/** Borderless style */
|
|
39
40
|
inset?: boolean;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type Component, createMemo, type JSX, splitProps } from "solid-js";
|
|
2
2
|
import { DateTime } from "@simplysm/core-common";
|
|
3
3
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
4
|
-
import {
|
|
4
|
+
import { fieldInputClass, getFieldWrapperClass } from "./Field.styles";
|
|
5
|
+
import type { ComponentSize } from "../../../styles/control.styles";
|
|
5
6
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
6
7
|
import { FieldShell } from "./FieldShell";
|
|
7
8
|
|
|
@@ -33,7 +34,7 @@ export interface DateTimePickerProps {
|
|
|
33
34
|
readOnly?: boolean;
|
|
34
35
|
|
|
35
36
|
/** Size */
|
|
36
|
-
size?:
|
|
37
|
+
size?: ComponentSize;
|
|
37
38
|
|
|
38
39
|
/** Borderless style */
|
|
39
40
|
inset?: boolean;
|
|
@@ -3,8 +3,6 @@ import { twMerge } from "tailwind-merge";
|
|
|
3
3
|
import { type ComponentSize, gap, pad } from "../../../styles/control.styles";
|
|
4
4
|
import { border, text } from "../../../styles/base.styles";
|
|
5
5
|
|
|
6
|
-
export type FieldSize = ComponentSize;
|
|
7
|
-
|
|
8
6
|
// ── Form Field Common Surface (background + text + border + focus) ──
|
|
9
7
|
export const fieldSurface = clsx(
|
|
10
8
|
"bg-primary-50 dark:bg-primary-950/30",
|
|
@@ -23,7 +21,7 @@ export const fieldBaseClass = clsx(
|
|
|
23
21
|
);
|
|
24
22
|
|
|
25
23
|
// Size-specific styles
|
|
26
|
-
export const fieldSizeClasses: Record<
|
|
24
|
+
export const fieldSizeClasses: Record<ComponentSize, string> = {
|
|
27
25
|
md: clsx("h-field", pad.md),
|
|
28
26
|
xs: clsx("h-field-xs", pad.xs),
|
|
29
27
|
sm: clsx("h-field-sm", pad.sm),
|
|
@@ -41,7 +39,7 @@ export const fieldInsetClass = clsx(
|
|
|
41
39
|
);
|
|
42
40
|
|
|
43
41
|
// Inset heights (excluding 2px border)
|
|
44
|
-
export const fieldInsetSizeHeightClasses: Record<
|
|
42
|
+
export const fieldInsetSizeHeightClasses: Record<ComponentSize, string> = {
|
|
45
43
|
md: clsx`h-field-inset`,
|
|
46
44
|
xs: clsx`h-field-inset-xs`,
|
|
47
45
|
sm: clsx`h-field-inset-sm`,
|
|
@@ -56,7 +54,7 @@ export const fieldDisabledClass = clsx("bg-base-100 text-base-500 dark:bg-base-8
|
|
|
56
54
|
export const textAreaBaseClass = clsx("inline-block w-48", fieldSurface);
|
|
57
55
|
|
|
58
56
|
// Textarea size-specific styles (h-field-* removed)
|
|
59
|
-
export const textAreaSizeClasses: Record<
|
|
57
|
+
export const textAreaSizeClasses: Record<ComponentSize, string> = {
|
|
60
58
|
md: pad.md,
|
|
61
59
|
xs: pad.xs,
|
|
62
60
|
sm: pad.sm,
|
|
@@ -74,7 +72,7 @@ export const fieldInputClass = clsx(
|
|
|
74
72
|
);
|
|
75
73
|
|
|
76
74
|
// Prefix icon gap classes (replaces nested ternary)
|
|
77
|
-
export const fieldGapClasses: Record<
|
|
75
|
+
export const fieldGapClasses: Record<ComponentSize, string> = {
|
|
78
76
|
md: gap.md,
|
|
79
77
|
xs: gap.xs,
|
|
80
78
|
sm: gap.sm,
|
|
@@ -84,7 +82,7 @@ export const fieldGapClasses: Record<FieldSize, string> = {
|
|
|
84
82
|
|
|
85
83
|
// Shared wrapper class generation function
|
|
86
84
|
export function getFieldWrapperClass(options: {
|
|
87
|
-
size?:
|
|
85
|
+
size?: ComponentSize;
|
|
88
86
|
disabled?: boolean;
|
|
89
87
|
inset?: boolean;
|
|
90
88
|
includeCustomClass?: string | false;
|
|
@@ -103,7 +101,7 @@ export function getFieldWrapperClass(options: {
|
|
|
103
101
|
|
|
104
102
|
// Textarea-specific wrapper class generation function
|
|
105
103
|
export function getTextareaWrapperClass(options: {
|
|
106
|
-
size?:
|
|
104
|
+
size?: ComponentSize;
|
|
107
105
|
disabled?: boolean;
|
|
108
106
|
inset?: boolean;
|
|
109
107
|
includeCustomClass?: string | false;
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
10
10
|
import { createSlot } from "../../../helpers/createSlot";
|
|
11
11
|
import {
|
|
12
|
-
type FieldSize,
|
|
13
12
|
fieldInputClass,
|
|
14
13
|
fieldGapClasses,
|
|
15
14
|
getFieldWrapperClass,
|
|
16
15
|
} from "./Field.styles";
|
|
16
|
+
import type { ComponentSize } from "../../../styles/control.styles";
|
|
17
17
|
import { PlaceholderFallback } from "./FieldPlaceholder";
|
|
18
18
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
19
19
|
import { FieldShell } from "./FieldShell";
|
|
@@ -49,7 +49,7 @@ export interface NumberInputProps {
|
|
|
49
49
|
readOnly?: boolean;
|
|
50
50
|
|
|
51
51
|
/** Size */
|
|
52
|
-
size?:
|
|
52
|
+
size?: ComponentSize;
|
|
53
53
|
|
|
54
54
|
/** Borderless style */
|
|
55
55
|
inset?: boolean;
|
|
@@ -332,6 +332,7 @@ const NumberInputInner = (props: NumberInputProps): JSX.Element => {
|
|
|
332
332
|
)}
|
|
333
333
|
value={displayValue()}
|
|
334
334
|
placeholder={local.placeholder}
|
|
335
|
+
|
|
335
336
|
title={local.title}
|
|
336
337
|
autocomplete="one-time-code"
|
|
337
338
|
onInput={handleInput}
|
|
@@ -5,9 +5,9 @@ import { createIMEHandler } from "../../../hooks/createIMEHandler";
|
|
|
5
5
|
import {
|
|
6
6
|
fieldGapClasses,
|
|
7
7
|
fieldInputClass,
|
|
8
|
-
type FieldSize,
|
|
9
8
|
getFieldWrapperClass,
|
|
10
9
|
} from "./Field.styles";
|
|
10
|
+
import type { ComponentSize } from "../../../styles/control.styles";
|
|
11
11
|
import { PlaceholderFallback } from "./FieldPlaceholder";
|
|
12
12
|
import { FieldShell } from "./FieldShell";
|
|
13
13
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
@@ -41,7 +41,7 @@ export interface TextInputProps {
|
|
|
41
41
|
readOnly?: boolean;
|
|
42
42
|
|
|
43
43
|
/** Size */
|
|
44
|
-
size?:
|
|
44
|
+
size?: ComponentSize;
|
|
45
45
|
|
|
46
46
|
/** Borderless style */
|
|
47
47
|
inset?: boolean;
|
|
@@ -286,6 +286,7 @@ const TextInputInner = (props: TextInputProps) => {
|
|
|
286
286
|
class={fieldInputClass}
|
|
287
287
|
value={inputValue()}
|
|
288
288
|
placeholder={local.placeholder}
|
|
289
|
+
|
|
289
290
|
title={local.title}
|
|
290
291
|
autocomplete={local.autocomplete ?? "one-time-code"}
|
|
291
292
|
onInput={handleInput}
|
|
@@ -4,7 +4,8 @@ import { twMerge } from "tailwind-merge";
|
|
|
4
4
|
import { text } from "../../../styles/base.styles";
|
|
5
5
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
6
6
|
import { createIMEHandler } from "../../../hooks/createIMEHandler";
|
|
7
|
-
import {
|
|
7
|
+
import { textAreaSizeClasses, getTextareaWrapperClass } from "./Field.styles";
|
|
8
|
+
import type { ComponentSize } from "../../../styles/control.styles";
|
|
8
9
|
import { PlaceholderFallback } from "./FieldPlaceholder";
|
|
9
10
|
import { FieldShell } from "./FieldShell";
|
|
10
11
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
@@ -29,7 +30,7 @@ export interface TextareaProps {
|
|
|
29
30
|
readOnly?: boolean;
|
|
30
31
|
|
|
31
32
|
/** Size */
|
|
32
|
-
size?:
|
|
33
|
+
size?: ComponentSize;
|
|
33
34
|
|
|
34
35
|
/** Borderless style */
|
|
35
36
|
inset?: boolean;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type Component, createMemo, type JSX, splitProps } from "solid-js";
|
|
2
2
|
import { Time } from "@simplysm/core-common";
|
|
3
3
|
import { createControllableSignal } from "../../../hooks/createControllableSignal";
|
|
4
|
-
import {
|
|
4
|
+
import { fieldInputClass, getFieldWrapperClass } from "./Field.styles";
|
|
5
|
+
import type { ComponentSize } from "../../../styles/control.styles";
|
|
5
6
|
import { useI18n } from "../../../providers/i18n/I18nProvider";
|
|
6
7
|
import { FieldShell } from "./FieldShell";
|
|
7
8
|
|
|
@@ -27,7 +28,7 @@ export interface TimePickerProps {
|
|
|
27
28
|
readOnly?: boolean;
|
|
28
29
|
|
|
29
30
|
/** Size */
|
|
30
|
-
size?:
|
|
31
|
+
size?: ComponentSize;
|
|
31
32
|
|
|
32
33
|
/** Borderless style */
|
|
33
34
|
inset?: boolean;
|
|
@@ -127,7 +127,7 @@ export const Numpad: Component<NumpadProps> = (props) => {
|
|
|
127
127
|
setInputStr(valueToInputStr(val));
|
|
128
128
|
};
|
|
129
129
|
|
|
130
|
-
const buttonSize = () => props.size ?? "
|
|
130
|
+
const buttonSize = () => props.size ?? "md";
|
|
131
131
|
|
|
132
132
|
return (
|
|
133
133
|
<div data-numpad class={twMerge(clsx("grid grid-cols-3", gap.sm, "w-auto"), props.class)} style={props.style}>
|
|
@@ -138,7 +138,7 @@ export const Numpad: Component<NumpadProps> = (props) => {
|
|
|
138
138
|
onValueChange={handleFieldValueChange}
|
|
139
139
|
placeholder={props.placeholder}
|
|
140
140
|
readOnly={props.inputDisabled}
|
|
141
|
-
|
|
141
|
+
size={buttonSize()}
|
|
142
142
|
class="w-full"
|
|
143
143
|
useGrouping={false}
|
|
144
144
|
/>
|
|
@@ -148,7 +148,6 @@ export const Numpad: Component<NumpadProps> = (props) => {
|
|
|
148
148
|
theme="primary"
|
|
149
149
|
variant="solid"
|
|
150
150
|
size={buttonSize()}
|
|
151
|
-
inset
|
|
152
151
|
disabled={props.required && value() == null}
|
|
153
152
|
onClick={handleEnter}
|
|
154
153
|
>
|
|
@@ -158,60 +157,59 @@ export const Numpad: Component<NumpadProps> = (props) => {
|
|
|
158
157
|
|
|
159
158
|
{/* Row 2: optional Minus + C + BS */}
|
|
160
159
|
<Show when={props.withMinusButton}>
|
|
161
|
-
<Button size={buttonSize()}
|
|
160
|
+
<Button size={buttonSize()} onClick={handleMinus}>
|
|
162
161
|
-
|
|
163
162
|
</Button>
|
|
164
163
|
</Show>
|
|
165
164
|
<Button
|
|
166
165
|
size={buttonSize()}
|
|
167
|
-
|
|
168
|
-
onClick={handleClear}
|
|
166
|
+
onClick={handleClear}
|
|
169
167
|
class={clsx(props.withMinusButton ? "col-span-1" : "col-span-2", "text-danger-500")}
|
|
170
168
|
>
|
|
171
169
|
<Icon icon={IconEraser} />
|
|
172
170
|
</Button>
|
|
173
|
-
<Button size={buttonSize()}
|
|
171
|
+
<Button size={buttonSize()} onClick={handleBackspace} class="text-warning-500">
|
|
174
172
|
<Icon icon={IconArrowLeft} />
|
|
175
173
|
</Button>
|
|
176
174
|
|
|
177
175
|
{/* Row 3: 7 8 9 */}
|
|
178
|
-
<Button size={buttonSize()}
|
|
176
|
+
<Button size={buttonSize()} onClick={() => handleDigit("7")}>
|
|
179
177
|
7
|
|
180
178
|
</Button>
|
|
181
|
-
<Button size={buttonSize()}
|
|
179
|
+
<Button size={buttonSize()} onClick={() => handleDigit("8")}>
|
|
182
180
|
8
|
|
183
181
|
</Button>
|
|
184
|
-
<Button size={buttonSize()}
|
|
182
|
+
<Button size={buttonSize()} onClick={() => handleDigit("9")}>
|
|
185
183
|
9
|
|
186
184
|
</Button>
|
|
187
185
|
|
|
188
186
|
{/* Row 4: 4 5 6 */}
|
|
189
|
-
<Button size={buttonSize()}
|
|
187
|
+
<Button size={buttonSize()} onClick={() => handleDigit("4")}>
|
|
190
188
|
4
|
|
191
189
|
</Button>
|
|
192
|
-
<Button size={buttonSize()}
|
|
190
|
+
<Button size={buttonSize()} onClick={() => handleDigit("5")}>
|
|
193
191
|
5
|
|
194
192
|
</Button>
|
|
195
|
-
<Button size={buttonSize()}
|
|
193
|
+
<Button size={buttonSize()} onClick={() => handleDigit("6")}>
|
|
196
194
|
6
|
|
197
195
|
</Button>
|
|
198
196
|
|
|
199
197
|
{/* Row 5: 1 2 3 */}
|
|
200
|
-
<Button size={buttonSize()}
|
|
198
|
+
<Button size={buttonSize()} onClick={() => handleDigit("1")}>
|
|
201
199
|
1
|
|
202
200
|
</Button>
|
|
203
|
-
<Button size={buttonSize()}
|
|
201
|
+
<Button size={buttonSize()} onClick={() => handleDigit("2")}>
|
|
204
202
|
2
|
|
205
203
|
</Button>
|
|
206
|
-
<Button size={buttonSize()}
|
|
204
|
+
<Button size={buttonSize()} onClick={() => handleDigit("3")}>
|
|
207
205
|
3
|
|
208
206
|
</Button>
|
|
209
207
|
|
|
210
208
|
{/* Row 6: 0 (colspan 2) + . */}
|
|
211
|
-
<Button size={buttonSize()}
|
|
209
|
+
<Button size={buttonSize()} class="col-span-2" onClick={() => handleDigit("0")}>
|
|
212
210
|
0
|
|
213
211
|
</Button>
|
|
214
|
-
<Button size={buttonSize()}
|
|
212
|
+
<Button size={buttonSize()} onClick={handleDot}>
|
|
215
213
|
.
|
|
216
214
|
</Button>
|
|
217
215
|
</div>
|
|
@@ -38,7 +38,10 @@ import {
|
|
|
38
38
|
listItemIndentGuideClass,
|
|
39
39
|
listItemContentClass,
|
|
40
40
|
getListItemSelectedIconClass,
|
|
41
|
+
listItemBasePadLeft,
|
|
42
|
+
LIST_ITEM_INDENT_SIZE,
|
|
41
43
|
} from "../../data/list/ListItem.styles";
|
|
44
|
+
import { useListContext } from "../../data/list/ListContext";
|
|
42
45
|
|
|
43
46
|
void ripple;
|
|
44
47
|
|
|
@@ -108,6 +111,7 @@ const SelectAction = (props: SelectActionProps) => {
|
|
|
108
111
|
<button
|
|
109
112
|
{...rest}
|
|
110
113
|
type="button"
|
|
114
|
+
use:ripple={!rest.disabled}
|
|
111
115
|
onClick={handleClick}
|
|
112
116
|
class={twMerge(
|
|
113
117
|
"inline-flex items-center",
|
|
@@ -177,9 +181,11 @@ export interface SelectItemProps<TValue = unknown> extends Omit<
|
|
|
177
181
|
const SelectItemInner = <TValue,>(
|
|
178
182
|
props: SelectItemProps<TValue> & { children?: JSX.Element },
|
|
179
183
|
) => {
|
|
180
|
-
const [local, rest] = splitProps(props, ["children", "class", "value", "disabled"]);
|
|
184
|
+
const [local, rest] = splitProps(props, ["children", "class", "style", "value", "disabled"]);
|
|
181
185
|
|
|
182
186
|
const context = useSelectContext<TValue>();
|
|
187
|
+
const listContext = useListContext();
|
|
188
|
+
const level = listContext.level;
|
|
183
189
|
|
|
184
190
|
const [childrenSlot, ItemChildrenProvider] = createItemChildrenSlotAccessor();
|
|
185
191
|
const hasChildren = () => childrenSlot() !== undefined;
|
|
@@ -206,6 +212,13 @@ const SelectItemInner = <TValue,>(
|
|
|
206
212
|
local.class,
|
|
207
213
|
);
|
|
208
214
|
|
|
215
|
+
const indentPaddingLeft = level >= 1
|
|
216
|
+
? `${listItemBasePadLeft[context.size()] + level * LIST_ITEM_INDENT_SIZE}rem`
|
|
217
|
+
: undefined;
|
|
218
|
+
|
|
219
|
+
const getGuideLeft = () =>
|
|
220
|
+
`${listItemBasePadLeft[context.size()] + level * LIST_ITEM_INDENT_SIZE + LIST_ITEM_INDENT_SIZE * 0.5}rem`;
|
|
221
|
+
|
|
209
222
|
return (
|
|
210
223
|
<ItemChildrenProvider>
|
|
211
224
|
<button
|
|
@@ -213,6 +226,7 @@ const SelectItemInner = <TValue,>(
|
|
|
213
226
|
type="button"
|
|
214
227
|
use:ripple={useRipple()}
|
|
215
228
|
class={getClassName()}
|
|
229
|
+
style={{ ...(local.style as JSX.CSSProperties), "padding-left": indentPaddingLeft }}
|
|
216
230
|
data-select-item
|
|
217
231
|
data-list-item
|
|
218
232
|
role="option"
|
|
@@ -228,9 +242,9 @@ const SelectItemInner = <TValue,>(
|
|
|
228
242
|
</button>
|
|
229
243
|
<Show when={hasChildren()}>
|
|
230
244
|
<Collapse open={true}>
|
|
231
|
-
<div class="
|
|
232
|
-
<div class={listItemIndentGuideClass} />
|
|
233
|
-
<List inset
|
|
245
|
+
<div class="relative">
|
|
246
|
+
<div class={listItemIndentGuideClass} style={{ left: getGuideLeft() }} />
|
|
247
|
+
<List inset>
|
|
234
248
|
{childrenSlot()!.children}
|
|
235
249
|
</List>
|
|
236
250
|
</div>
|
|
@@ -622,7 +636,7 @@ const SelectInnerComponent = <TValue,>(props: SelectProps<TValue>) => {
|
|
|
622
636
|
local.multiple === true && !local.hideSelectAll && local.items !== undefined;
|
|
623
637
|
|
|
624
638
|
return (
|
|
625
|
-
<div {...rest} data-select class={clsx("group", local.inset ? "flex" : "inline-flex")}>
|
|
639
|
+
<div {...rest} data-select class={clsx("group", local.inset ? "flex" : "inline-flex", "[&>[data-dropdown-trigger]]:flex")}>
|
|
626
640
|
<Dropdown disabled={local.disabled} open={open()} onOpenChange={setOpen} keyboardNav>
|
|
627
641
|
<Dropdown.Trigger>
|
|
628
642
|
<div
|