@lobb-js/studio 0.14.0 → 0.15.0
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.
|
@@ -8,26 +8,47 @@
|
|
|
8
8
|
|
|
9
9
|
const { value, enum: enumOptions }: Props = $props();
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
const colorClasses: Record<string, string> = {
|
|
12
|
+
red: "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800",
|
|
13
|
+
rose: "bg-rose-100 text-rose-700 border-rose-200 dark:bg-rose-900/30 dark:text-rose-300 dark:border-rose-800",
|
|
14
|
+
pink: "bg-pink-100 text-pink-700 border-pink-200 dark:bg-pink-900/30 dark:text-pink-300 dark:border-pink-800",
|
|
15
|
+
fuchsia: "bg-fuchsia-100 text-fuchsia-700 border-fuchsia-200 dark:bg-fuchsia-900/30 dark:text-fuchsia-300 dark:border-fuchsia-800",
|
|
16
|
+
purple: "bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-900/30 dark:text-purple-300 dark:border-purple-800",
|
|
17
|
+
violet: "bg-violet-100 text-violet-700 border-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:border-violet-800",
|
|
18
|
+
indigo: "bg-indigo-100 text-indigo-700 border-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-300 dark:border-indigo-800",
|
|
19
|
+
blue: "bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/30 dark:text-blue-300 dark:border-blue-800",
|
|
20
|
+
sky: "bg-sky-100 text-sky-700 border-sky-200 dark:bg-sky-900/30 dark:text-sky-300 dark:border-sky-800",
|
|
21
|
+
cyan: "bg-cyan-100 text-cyan-700 border-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-300 dark:border-cyan-800",
|
|
22
|
+
teal: "bg-teal-100 text-teal-700 border-teal-200 dark:bg-teal-900/30 dark:text-teal-300 dark:border-teal-800",
|
|
23
|
+
emerald: "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800",
|
|
24
|
+
green: "bg-green-100 text-green-700 border-green-200 dark:bg-green-900/30 dark:text-green-300 dark:border-green-800",
|
|
25
|
+
lime: "bg-lime-100 text-lime-700 border-lime-200 dark:bg-lime-900/30 dark:text-lime-300 dark:border-lime-800",
|
|
26
|
+
yellow: "bg-yellow-100 text-yellow-700 border-yellow-300 dark:bg-yellow-900/30 dark:text-yellow-300 dark:border-yellow-800",
|
|
27
|
+
amber: "bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-800",
|
|
28
|
+
orange: "bg-orange-100 text-orange-700 border-orange-200 dark:bg-orange-900/30 dark:text-orange-300 dark:border-orange-800",
|
|
29
|
+
slate: "bg-slate-100 text-slate-600 border-slate-200 dark:bg-slate-800/50 dark:text-slate-300 dark:border-slate-700",
|
|
30
|
+
zinc: "bg-zinc-100 text-zinc-600 border-zinc-200 dark:bg-zinc-800/50 dark:text-zinc-300 dark:border-zinc-700",
|
|
31
|
+
gray: "bg-gray-100 text-gray-600 border-gray-200 dark:bg-gray-800/50 dark:text-gray-300 dark:border-gray-700",
|
|
32
|
+
stone: "bg-stone-100 text-stone-600 border-stone-200 dark:bg-stone-800/50 dark:text-stone-300 dark:border-stone-700",
|
|
33
|
+
neutral: "bg-neutral-100 text-neutral-600 border-neutral-200 dark:bg-neutral-800/50 dark:text-neutral-300 dark:border-neutral-700",
|
|
18
34
|
};
|
|
19
35
|
|
|
20
36
|
const normalizedOptions = $derived(
|
|
21
|
-
(enumOptions as Array<string | EnumOption>).map((e) =>
|
|
22
|
-
typeof e === "
|
|
37
|
+
(enumOptions as Array<string | number | EnumOption>).map((e) =>
|
|
38
|
+
typeof e === "object" ? e : { value: e, color: undefined, description: undefined },
|
|
23
39
|
),
|
|
24
40
|
);
|
|
25
41
|
|
|
26
|
-
const enumOption = $derived(normalizedOptions.find((e) => e.value === value));
|
|
42
|
+
const enumOption = $derived(normalizedOptions.find((e) => String(e.value) === String(value)));
|
|
27
43
|
</script>
|
|
28
44
|
|
|
29
45
|
{#if enumOption}
|
|
30
|
-
<span class="
|
|
31
|
-
{
|
|
46
|
+
<span class="flex items-center gap-1.5">
|
|
47
|
+
<span class="px-2 py-0.5 rounded-full text-xs font-medium border {enumOption.color ? colorClasses[enumOption.color] : colorClasses['gray']}">
|
|
48
|
+
{enumOption.value}
|
|
49
|
+
</span>
|
|
50
|
+
{#if enumOption.description}
|
|
51
|
+
<span class="text-xs text-muted-foreground">{enumOption.description}</span>
|
|
52
|
+
{/if}
|
|
32
53
|
</span>
|
|
33
54
|
{/if}
|
|
@@ -93,75 +93,60 @@
|
|
|
93
93
|
{destructive}
|
|
94
94
|
/>
|
|
95
95
|
</ExtensionsComponents>
|
|
96
|
-
{:else if field.
|
|
97
|
-
{@const rawEnum = field.enum as (string | EnumOption)[]}
|
|
98
|
-
{@const
|
|
96
|
+
{:else if field.enum}
|
|
97
|
+
{@const rawEnum = field.enum as (string | number | EnumOption)[]}
|
|
98
|
+
{@const isEnumOption = rawEnum.length > 0 && typeof rawEnum[0] === "object"}
|
|
99
|
+
{@const enumOptions = isEnumOption ? rawEnum as EnumOption[] : undefined}
|
|
99
100
|
<Select.Root
|
|
100
101
|
type="single"
|
|
101
|
-
|
|
102
|
-
value
|
|
103
|
-
|
|
102
|
+
bind:value={
|
|
103
|
+
() => value != null ? String(value) : null,
|
|
104
|
+
(v) => {
|
|
105
|
+
if (v == null) { value = null; return; }
|
|
106
|
+
const isNumeric = field.type === "integer" || field.type === "long" || field.type === "decimal" || field.type === "float";
|
|
107
|
+
value = isNumeric ? Number(v) : v;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
104
110
|
>
|
|
105
111
|
<Select.Trigger
|
|
106
|
-
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
107
112
|
class="
|
|
108
113
|
h-9 w-full bg-muted/30 pr-8
|
|
109
114
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
110
115
|
"
|
|
111
116
|
>
|
|
112
|
-
{#if value}
|
|
113
|
-
<EnumBadge {value} enum={enumOptions} />
|
|
117
|
+
{#if value != null && enumOptions}
|
|
118
|
+
<EnumBadge value={String(value)} enum={enumOptions} />
|
|
119
|
+
{:else if value != null}
|
|
120
|
+
{value}
|
|
114
121
|
{:else}
|
|
115
|
-
NULL
|
|
122
|
+
<span class="text-muted-foreground">{ui?.placeholder ?? "NULL"}</span>
|
|
116
123
|
{/if}
|
|
117
124
|
</Select.Trigger>
|
|
118
125
|
<Select.Content>
|
|
119
126
|
<Select.Group>
|
|
120
|
-
{#each
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
{#each rawEnum as option}
|
|
128
|
+
{@const optionValue = typeof option === "object" ? String(option.value) : String(option)}
|
|
129
|
+
<Select.Item value={optionValue} label={optionValue}>
|
|
130
|
+
{#if enumOptions}
|
|
131
|
+
<EnumBadge value={optionValue} enum={enumOptions} />
|
|
132
|
+
{:else}
|
|
133
|
+
{optionValue}
|
|
134
|
+
{/if}
|
|
123
135
|
</Select.Item>
|
|
124
136
|
{/each}
|
|
125
137
|
</Select.Group>
|
|
126
138
|
</Select.Content>
|
|
127
139
|
</Select.Root>
|
|
128
140
|
{:else if field.type === "string"}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
139
|
-
class="
|
|
140
|
-
h-9 w-full bg-muted/30 pr-8
|
|
141
|
-
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
142
|
-
"
|
|
143
|
-
>
|
|
144
|
-
{value ? value : "NULL"}
|
|
145
|
-
</Select.Trigger>
|
|
146
|
-
<Select.Content>
|
|
147
|
-
<Select.Group>
|
|
148
|
-
{#each field.validators.enum as option}
|
|
149
|
-
<Select.Item value={option} label={option} />
|
|
150
|
-
{/each}
|
|
151
|
-
</Select.Group>
|
|
152
|
-
</Select.Content>
|
|
153
|
-
</Select.Root>
|
|
154
|
-
{:else}
|
|
155
|
-
<Input
|
|
156
|
-
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
157
|
-
type="text"
|
|
158
|
-
class="
|
|
159
|
-
bg-muted/30 text-xs
|
|
160
|
-
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
161
|
-
"
|
|
162
|
-
bind:value
|
|
163
|
-
/>
|
|
164
|
-
{/if}
|
|
141
|
+
<Input
|
|
142
|
+
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
143
|
+
type="text"
|
|
144
|
+
class="
|
|
145
|
+
bg-muted/30 text-xs
|
|
146
|
+
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
147
|
+
"
|
|
148
|
+
bind:value
|
|
149
|
+
/>
|
|
165
150
|
{:else if field.type === "text"}
|
|
166
151
|
<Textarea
|
|
167
152
|
placeholder={ui?.placeholder ? ui.placeholder : value === "" ? "EMPTY STRING" : "NULL"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobb-js/studio",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.15.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
7
7
|
"access": "public"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"postpublish": "./scripts/postpublish.sh"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@lobb-js/core": "^0.
|
|
45
|
+
"@lobb-js/core": "^0.21.0",
|
|
46
46
|
"@chromatic-com/storybook": "^4.1.2",
|
|
47
47
|
"@storybook/addon-a11y": "^10.0.1",
|
|
48
48
|
"@storybook/addon-docs": "^10.0.1",
|
|
@@ -8,26 +8,47 @@
|
|
|
8
8
|
|
|
9
9
|
const { value, enum: enumOptions }: Props = $props();
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
const colorClasses: Record<string, string> = {
|
|
12
|
+
red: "bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-300 dark:border-red-800",
|
|
13
|
+
rose: "bg-rose-100 text-rose-700 border-rose-200 dark:bg-rose-900/30 dark:text-rose-300 dark:border-rose-800",
|
|
14
|
+
pink: "bg-pink-100 text-pink-700 border-pink-200 dark:bg-pink-900/30 dark:text-pink-300 dark:border-pink-800",
|
|
15
|
+
fuchsia: "bg-fuchsia-100 text-fuchsia-700 border-fuchsia-200 dark:bg-fuchsia-900/30 dark:text-fuchsia-300 dark:border-fuchsia-800",
|
|
16
|
+
purple: "bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-900/30 dark:text-purple-300 dark:border-purple-800",
|
|
17
|
+
violet: "bg-violet-100 text-violet-700 border-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:border-violet-800",
|
|
18
|
+
indigo: "bg-indigo-100 text-indigo-700 border-indigo-200 dark:bg-indigo-900/30 dark:text-indigo-300 dark:border-indigo-800",
|
|
19
|
+
blue: "bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/30 dark:text-blue-300 dark:border-blue-800",
|
|
20
|
+
sky: "bg-sky-100 text-sky-700 border-sky-200 dark:bg-sky-900/30 dark:text-sky-300 dark:border-sky-800",
|
|
21
|
+
cyan: "bg-cyan-100 text-cyan-700 border-cyan-200 dark:bg-cyan-900/30 dark:text-cyan-300 dark:border-cyan-800",
|
|
22
|
+
teal: "bg-teal-100 text-teal-700 border-teal-200 dark:bg-teal-900/30 dark:text-teal-300 dark:border-teal-800",
|
|
23
|
+
emerald: "bg-emerald-100 text-emerald-700 border-emerald-200 dark:bg-emerald-900/30 dark:text-emerald-300 dark:border-emerald-800",
|
|
24
|
+
green: "bg-green-100 text-green-700 border-green-200 dark:bg-green-900/30 dark:text-green-300 dark:border-green-800",
|
|
25
|
+
lime: "bg-lime-100 text-lime-700 border-lime-200 dark:bg-lime-900/30 dark:text-lime-300 dark:border-lime-800",
|
|
26
|
+
yellow: "bg-yellow-100 text-yellow-700 border-yellow-300 dark:bg-yellow-900/30 dark:text-yellow-300 dark:border-yellow-800",
|
|
27
|
+
amber: "bg-amber-100 text-amber-700 border-amber-200 dark:bg-amber-900/30 dark:text-amber-300 dark:border-amber-800",
|
|
28
|
+
orange: "bg-orange-100 text-orange-700 border-orange-200 dark:bg-orange-900/30 dark:text-orange-300 dark:border-orange-800",
|
|
29
|
+
slate: "bg-slate-100 text-slate-600 border-slate-200 dark:bg-slate-800/50 dark:text-slate-300 dark:border-slate-700",
|
|
30
|
+
zinc: "bg-zinc-100 text-zinc-600 border-zinc-200 dark:bg-zinc-800/50 dark:text-zinc-300 dark:border-zinc-700",
|
|
31
|
+
gray: "bg-gray-100 text-gray-600 border-gray-200 dark:bg-gray-800/50 dark:text-gray-300 dark:border-gray-700",
|
|
32
|
+
stone: "bg-stone-100 text-stone-600 border-stone-200 dark:bg-stone-800/50 dark:text-stone-300 dark:border-stone-700",
|
|
33
|
+
neutral: "bg-neutral-100 text-neutral-600 border-neutral-200 dark:bg-neutral-800/50 dark:text-neutral-300 dark:border-neutral-700",
|
|
18
34
|
};
|
|
19
35
|
|
|
20
36
|
const normalizedOptions = $derived(
|
|
21
|
-
(enumOptions as Array<string | EnumOption>).map((e) =>
|
|
22
|
-
typeof e === "
|
|
37
|
+
(enumOptions as Array<string | number | EnumOption>).map((e) =>
|
|
38
|
+
typeof e === "object" ? e : { value: e, color: undefined, description: undefined },
|
|
23
39
|
),
|
|
24
40
|
);
|
|
25
41
|
|
|
26
|
-
const enumOption = $derived(normalizedOptions.find((e) => e.value === value));
|
|
42
|
+
const enumOption = $derived(normalizedOptions.find((e) => String(e.value) === String(value)));
|
|
27
43
|
</script>
|
|
28
44
|
|
|
29
45
|
{#if enumOption}
|
|
30
|
-
<span class="
|
|
31
|
-
{
|
|
46
|
+
<span class="flex items-center gap-1.5">
|
|
47
|
+
<span class="px-2 py-0.5 rounded-full text-xs font-medium border {enumOption.color ? colorClasses[enumOption.color] : colorClasses['gray']}">
|
|
48
|
+
{enumOption.value}
|
|
49
|
+
</span>
|
|
50
|
+
{#if enumOption.description}
|
|
51
|
+
<span class="text-xs text-muted-foreground">{enumOption.description}</span>
|
|
52
|
+
{/if}
|
|
32
53
|
</span>
|
|
33
54
|
{/if}
|
|
@@ -93,75 +93,60 @@
|
|
|
93
93
|
{destructive}
|
|
94
94
|
/>
|
|
95
95
|
</ExtensionsComponents>
|
|
96
|
-
{:else if field.
|
|
97
|
-
{@const rawEnum = field.enum as (string | EnumOption)[]}
|
|
98
|
-
{@const
|
|
96
|
+
{:else if field.enum}
|
|
97
|
+
{@const rawEnum = field.enum as (string | number | EnumOption)[]}
|
|
98
|
+
{@const isEnumOption = rawEnum.length > 0 && typeof rawEnum[0] === "object"}
|
|
99
|
+
{@const enumOptions = isEnumOption ? rawEnum as EnumOption[] : undefined}
|
|
99
100
|
<Select.Root
|
|
100
101
|
type="single"
|
|
101
|
-
|
|
102
|
-
value
|
|
103
|
-
|
|
102
|
+
bind:value={
|
|
103
|
+
() => value != null ? String(value) : null,
|
|
104
|
+
(v) => {
|
|
105
|
+
if (v == null) { value = null; return; }
|
|
106
|
+
const isNumeric = field.type === "integer" || field.type === "long" || field.type === "decimal" || field.type === "float";
|
|
107
|
+
value = isNumeric ? Number(v) : v;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
104
110
|
>
|
|
105
111
|
<Select.Trigger
|
|
106
|
-
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
107
112
|
class="
|
|
108
113
|
h-9 w-full bg-muted/30 pr-8
|
|
109
114
|
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
110
115
|
"
|
|
111
116
|
>
|
|
112
|
-
{#if value}
|
|
113
|
-
<EnumBadge {value} enum={enumOptions} />
|
|
117
|
+
{#if value != null && enumOptions}
|
|
118
|
+
<EnumBadge value={String(value)} enum={enumOptions} />
|
|
119
|
+
{:else if value != null}
|
|
120
|
+
{value}
|
|
114
121
|
{:else}
|
|
115
|
-
NULL
|
|
122
|
+
<span class="text-muted-foreground">{ui?.placeholder ?? "NULL"}</span>
|
|
116
123
|
{/if}
|
|
117
124
|
</Select.Trigger>
|
|
118
125
|
<Select.Content>
|
|
119
126
|
<Select.Group>
|
|
120
|
-
{#each
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
{#each rawEnum as option}
|
|
128
|
+
{@const optionValue = typeof option === "object" ? String(option.value) : String(option)}
|
|
129
|
+
<Select.Item value={optionValue} label={optionValue}>
|
|
130
|
+
{#if enumOptions}
|
|
131
|
+
<EnumBadge value={optionValue} enum={enumOptions} />
|
|
132
|
+
{:else}
|
|
133
|
+
{optionValue}
|
|
134
|
+
{/if}
|
|
123
135
|
</Select.Item>
|
|
124
136
|
{/each}
|
|
125
137
|
</Select.Group>
|
|
126
138
|
</Select.Content>
|
|
127
139
|
</Select.Root>
|
|
128
140
|
{:else if field.type === "string"}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
139
|
-
class="
|
|
140
|
-
h-9 w-full bg-muted/30 pr-8
|
|
141
|
-
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
142
|
-
"
|
|
143
|
-
>
|
|
144
|
-
{value ? value : "NULL"}
|
|
145
|
-
</Select.Trigger>
|
|
146
|
-
<Select.Content>
|
|
147
|
-
<Select.Group>
|
|
148
|
-
{#each field.validators.enum as option}
|
|
149
|
-
<Select.Item value={option} label={option} />
|
|
150
|
-
{/each}
|
|
151
|
-
</Select.Group>
|
|
152
|
-
</Select.Content>
|
|
153
|
-
</Select.Root>
|
|
154
|
-
{:else}
|
|
155
|
-
<Input
|
|
156
|
-
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
157
|
-
type="text"
|
|
158
|
-
class="
|
|
159
|
-
bg-muted/30 text-xs
|
|
160
|
-
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
161
|
-
"
|
|
162
|
-
bind:value
|
|
163
|
-
/>
|
|
164
|
-
{/if}
|
|
141
|
+
<Input
|
|
142
|
+
placeholder={ui?.placeholder ? ui.placeholder : "NULL"}
|
|
143
|
+
type="text"
|
|
144
|
+
class="
|
|
145
|
+
bg-muted/30 text-xs
|
|
146
|
+
{destructive ? 'border-destructive bg-destructive/10' : ''}
|
|
147
|
+
"
|
|
148
|
+
bind:value
|
|
149
|
+
/>
|
|
165
150
|
{:else if field.type === "text"}
|
|
166
151
|
<Textarea
|
|
167
152
|
placeholder={ui?.placeholder ? ui.placeholder : value === "" ? "EMPTY STRING" : "NULL"}
|