@stacksjs/components 0.2.176 → 0.2.178
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/dist/{Accordion-pt8j917s.stx → Accordion-8tv78bh9.stx} +4 -4
- package/dist/{AccordionItem-hbhzx63p.stx → AccordionItem-7bd3ga36.stx} +3 -3
- package/dist/{Audio-hjywk3qc.stx → Audio-y0sgq50z.stx} +3 -3
- package/dist/{Avatar-h3jmwcq0.stx → Avatar-rjvwnskf.stx} +2 -2
- package/dist/{Badge-k8dy3d53.stx → Badge-k52qmxcm.stx} +1 -1
- package/dist/{Breadcrumb-7f7s4d02.stx → Breadcrumb-sy5taqsn.stx} +7 -7
- package/dist/{Button-1vknasy3.stx → Button-wrwmnfpf.stx} +2 -2
- package/dist/{Calendar-reny0et7.stx → Calendar-gjjhhfnt.stx} +8 -8
- package/dist/{Card-c1g1fd1w.stx → Card-473a02fy.stx} +3 -3
- package/dist/{Checkbox-aqmq4cqv.stx → Checkbox-2s2a7n4h.stx} +4 -4
- package/dist/{Checkout-agt0ngpw.stx → Checkout-22wh3s22.stx} +1 -1
- package/dist/{ComboboxOption-hmxt3gte.stx → ComboboxOption-6yh7xk7q.stx} +2 -2
- package/dist/{CommandPaletteItem-mvk6q7a2.stx → CommandPaletteItem-chdw0070.stx} +1 -1
- package/dist/{DefaultPaymentMethod-shhf6aap.stx → DefaultPaymentMethod-6qrem3sg.stx} +8 -8
- package/dist/{DialogDescription-76prd1m2.stx → DialogDescription-gth4c2kx.stx} +1 -1
- package/dist/{Drawer-hrz7qcyp.stx → Drawer-jgepqr9j.stx} +1 -1
- package/dist/{DropdownItem-c7rz08e5.stx → DropdownItem-d8ht2bp5.stx} +1 -1
- package/dist/{Form-bpnpbymb.stx → Form-vbag14t1.stx} +1 -1
- package/dist/{ListboxOption-e0dtv1gc.stx → ListboxOption-4j070101.stx} +2 -2
- package/dist/{Login-gepemsth.stx → Login-2cp65d41.stx} +40 -22
- package/dist/{Navigator-rk2a5wvk.stx → Navigator-smpa7my4.stx} +12 -12
- package/dist/{NumberInput-g41gmd2c.stx → NumberInput-j9p5bm5y.stx} +7 -7
- package/dist/{Pagination-wtgxmzey.stx → Pagination-jbcjrfcs.stx} +3 -3
- package/dist/{PasswordInput-4rsq1gwb.stx → PasswordInput-4qykq1dz.stx} +8 -8
- package/dist/{PaymentMethods-x4vrx9yb.stx → PaymentMethods-2xy66bwk.stx} +11 -11
- package/dist/{Progress-9dhakbh4.stx → Progress-4h7dytq5.stx} +9 -9
- package/dist/{Radio-djtb5dpc.stx → Radio-ccm07b2m.stx} +4 -4
- package/dist/RadioGroup-eerw9gq7.stx +138 -0
- package/dist/{RadioGroupDescription-yej78fak.stx → RadioGroupDescription-z34r9avr.stx} +1 -1
- package/dist/{RadioGroupOption-s1d6r221.stx → RadioGroupOption-7pq7rw84.stx} +1 -1
- package/dist/{Select-1vnd0brz.stx → Select-zt72gg1e.stx} +4 -4
- package/dist/{SidebarItem-2a6n0be3.stx → SidebarItem-5v8atp7p.stx} +2 -2
- package/dist/{SidebarPinned-tvj28bm0.stx → SidebarPinned-rq05nrtd.stx} +3 -3
- package/dist/{Signup-hxm5hwkr.stx → Signup-cbncrtvd.stx} +29 -19
- package/dist/{Skeleton-v1pwa8nr.stx → Skeleton-wtwb97xd.stx} +1 -1
- package/dist/{Spinner-7dahavkd.stx → Spinner-ypya5tt2.stx} +8 -8
- package/dist/{StepperStep-wxgembat.stx → StepperStep-3ahq4d9m.stx} +3 -3
- package/dist/{SubscriptionCheckout-zy2ycrmw.stx → SubscriptionCheckout-7fdkwf04.stx} +40 -34
- package/dist/{Switch-p1bcr9ks.stx → Switch-hdta55a8.stx} +1 -1
- package/dist/{Table-6cx8az9h.stx → Table-0mc3fdek.stx} +1 -1
- package/dist/{TableBody-wf6t13j9.stx → TableBody-drxyz5jh.stx} +1 -1
- package/dist/{TableCell-ntx0edbn.stx → TableCell-8swtcq8s.stx} +1 -1
- package/dist/{TableHead-3k4hnm2k.stx → TableHead-e9xvjx2j.stx} +1 -1
- package/dist/{TableHeader-0eyzbqpz.stx → TableHeader-sxc77b4d.stx} +2 -2
- package/dist/{TableRow-z09p2ebf.stx → TableRow-xd542nvb.stx} +1 -1
- package/dist/{Tabs-79brys99.stx → Tabs-b4xsba1w.stx} +6 -6
- package/dist/{TextInput-g0vaz0pe.stx → TextInput-cefyyprt.stx} +9 -9
- package/dist/{Textarea-96kawv5c.stx → Textarea-xcdym703.stx} +6 -6
- package/dist/{TwoFactorChallenge-y5m3nk79.stx → TwoFactorChallenge-y7n4yrk9.stx} +8 -8
- package/dist/{Video-84j4pv6h.stx → Video-a0aeyexv.stx} +1 -1
- package/dist/{VirtualTable-f9crbfjr.stx → VirtualTable-jvm1784g.stx} +6 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +89 -55
- package/dist/theme/index.d.ts +92 -0
- package/package.json +3 -3
- package/src/index.ts +2 -0
- package/src/theme/index.ts +130 -0
- package/src/ui/accordion/Accordion.stx +4 -4
- package/src/ui/accordion/AccordionItem.stx +3 -3
- package/src/ui/audio/Audio.stx +3 -3
- package/src/ui/auth/Login.stx +40 -22
- package/src/ui/auth/Signup.stx +29 -19
- package/src/ui/auth/TwoFactorChallenge.stx +8 -8
- package/src/ui/avatar/Avatar.stx +2 -2
- package/src/ui/badge/Badge.stx +1 -1
- package/src/ui/breadcrumb/Breadcrumb.stx +7 -7
- package/src/ui/button/Button.stx +2 -2
- package/src/ui/calendar/Calendar.stx +8 -8
- package/src/ui/card/Card.stx +3 -3
- package/src/ui/checkbox/Checkbox.stx +4 -4
- package/src/ui/combobox/ComboboxOption.stx +2 -2
- package/src/ui/command-palette/CommandPaletteItem.stx +1 -1
- package/src/ui/dialog/DialogDescription.stx +1 -1
- package/src/ui/drawer/Drawer.stx +1 -1
- package/src/ui/dropdown/DropdownItem.stx +1 -1
- package/src/ui/form/Form.stx +1 -1
- package/src/ui/input/NumberInput.stx +7 -7
- package/src/ui/input/PasswordInput.stx +8 -8
- package/src/ui/input/TextInput.stx +9 -9
- package/src/ui/listbox/ListboxOption.stx +2 -2
- package/src/ui/navigator/Navigator.stx +12 -12
- package/src/ui/pagination/Pagination.stx +3 -3
- package/src/ui/payment/Checkout.stx +1 -1
- package/src/ui/payment/DefaultPaymentMethod.stx +8 -8
- package/src/ui/payment/PaymentMethods.stx +11 -11
- package/src/ui/payment/SubscriptionCheckout.stx +40 -34
- package/src/ui/progress/Progress.stx +9 -9
- package/src/ui/radio/Radio.stx +4 -4
- package/src/ui/radio-group/RadioGroup.stx +79 -1
- package/src/ui/radio-group/RadioGroupDescription.stx +1 -1
- package/src/ui/radio-group/RadioGroupOption.stx +1 -1
- package/src/ui/select/Select.stx +4 -4
- package/src/ui/sidebar/SidebarItem.stx +2 -2
- package/src/ui/sidebar/SidebarPinned.stx +3 -3
- package/src/ui/skeleton/Skeleton.stx +1 -1
- package/src/ui/spinner/Spinner.stx +8 -8
- package/src/ui/stepper/StepperStep.stx +3 -3
- package/src/ui/switch/Switch.stx +1 -1
- package/src/ui/table/Table.stx +1 -1
- package/src/ui/table/TableBody.stx +1 -1
- package/src/ui/table/TableCell.stx +1 -1
- package/src/ui/table/TableHead.stx +1 -1
- package/src/ui/table/TableHeader.stx +2 -2
- package/src/ui/table/TableRow.stx +1 -1
- package/src/ui/tabs/Tabs.stx +6 -6
- package/src/ui/textarea/Textarea.stx +6 -6
- package/src/ui/video/Video.stx +1 -1
- package/src/ui/virtual-table/VirtualTable.stx +6 -6
- package/dist/RadioGroup-qxmnm3xm.stx +0 -60
|
@@ -19,17 +19,17 @@ const sizeClasses = { sm: 'px-3 py-1.5 text-sm h-8', md: 'px-4 py-2 text-base h-
|
|
|
19
19
|
const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100'
|
|
20
20
|
const stateClasses = error
|
|
21
21
|
? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
|
|
22
|
-
: 'ring-
|
|
22
|
+
: 'ring-line-strong text-fg placeholder-fg-subtle focus:ring-accent'
|
|
23
23
|
const disabledClasses = disabled
|
|
24
|
-
? 'opacity-50 cursor-not-allowed bg-
|
|
24
|
+
? 'opacity-50 cursor-not-allowed bg-surface'
|
|
25
25
|
: readonly
|
|
26
|
-
? 'bg-
|
|
26
|
+
? 'bg-surface cursor-default'
|
|
27
27
|
: 'bg-white dark:bg-blue-gray-700'
|
|
28
28
|
const paddingClasses = showControls ? 'pr-10' : ''
|
|
29
29
|
|
|
30
30
|
export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${paddingClasses} ${inputClassName}`.trim()
|
|
31
|
-
export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-
|
|
32
|
-
export const helperClasses = `mt-2 text-sm ${error ? 'text-
|
|
31
|
+
export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-danger' : 'text-fg'}`.trim()
|
|
32
|
+
export const helperClasses = `mt-2 text-sm ${error ? 'text-danger' : 'text-fg-soft'}`.trim()
|
|
33
33
|
</script>
|
|
34
34
|
|
|
35
35
|
<script client>
|
|
@@ -97,7 +97,7 @@ defineExpose({ value: inputValue, increment, decrement })
|
|
|
97
97
|
<button
|
|
98
98
|
type="button"
|
|
99
99
|
@click="increment()"
|
|
100
|
-
class="flex items-center justify-center w-8 h-1/2 text-
|
|
100
|
+
class="flex items-center justify-center w-8 h-1/2 text-fg-subtle hover:text-fg-muted focus:outline-none border-b border-line-strong"
|
|
101
101
|
aria-label="Increment"
|
|
102
102
|
>
|
|
103
103
|
<svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
@@ -107,7 +107,7 @@ defineExpose({ value: inputValue, increment, decrement })
|
|
|
107
107
|
<button
|
|
108
108
|
type="button"
|
|
109
109
|
@click="decrement()"
|
|
110
|
-
class="flex items-center justify-center w-8 h-1/2 text-
|
|
110
|
+
class="flex items-center justify-center w-8 h-1/2 text-fg-subtle hover:text-fg-muted focus:outline-none"
|
|
111
111
|
aria-label="Decrement"
|
|
112
112
|
>
|
|
113
113
|
<svg class="h-3 w-3" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
@@ -7,9 +7,9 @@ export const showPrevNext = $props.showPrevNext ?? true
|
|
|
7
7
|
export const className = $props.className || ''
|
|
8
8
|
|
|
9
9
|
export const paginationClasses = `flex items-center gap-1 ${className}`.trim()
|
|
10
|
-
export const buttonClasses = `px-3 py-2 text-sm font-medium text-
|
|
11
|
-
export const activeButtonClasses = `px-3 py-2 text-sm font-medium text-white bg-
|
|
12
|
-
export const ellipsisClasses = `px-3 py-2 text-sm font-medium text-
|
|
10
|
+
export const buttonClasses = `px-3 py-2 text-sm font-medium text-fg-strong bg-white dark:bg-gray-800 border border-line-strong rounded-md hover:bg-surface focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-white dark:disabled:hover:bg-gray-800 transition-colors duration-150`.trim()
|
|
11
|
+
export const activeButtonClasses = `px-3 py-2 text-sm font-medium text-white bg-info-solid border border-info rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-gray-900`.trim()
|
|
12
|
+
export const ellipsisClasses = `px-3 py-2 text-sm font-medium text-fg-subtle`.trim()
|
|
13
13
|
export const iconClasses = `w-5 h-5`.trim()
|
|
14
14
|
</script>
|
|
15
15
|
|
|
@@ -18,16 +18,16 @@ const iconSizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
|
|
|
18
18
|
const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100 pr-10'
|
|
19
19
|
const stateClasses = error
|
|
20
20
|
? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
|
|
21
|
-
: 'ring-
|
|
21
|
+
: 'ring-line-strong text-fg placeholder-fg-subtle focus:ring-accent'
|
|
22
22
|
const disabledClasses = disabled
|
|
23
|
-
? 'opacity-50 cursor-not-allowed bg-
|
|
23
|
+
? 'opacity-50 cursor-not-allowed bg-surface'
|
|
24
24
|
: readonly
|
|
25
|
-
? 'bg-
|
|
25
|
+
? 'bg-surface cursor-default'
|
|
26
26
|
: 'bg-white dark:bg-blue-gray-700'
|
|
27
27
|
|
|
28
28
|
export const inputClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${inputClassName}`.trim()
|
|
29
|
-
export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-
|
|
30
|
-
export const helperClasses = `mt-2 text-sm ${error ? 'text-
|
|
29
|
+
export const labelClasses = `block text-sm font-medium leading-6 mb-2 ${error ? 'text-danger' : 'text-fg'}`.trim()
|
|
30
|
+
export const helperClasses = `mt-2 text-sm ${error ? 'text-danger' : 'text-fg-soft'}`.trim()
|
|
31
31
|
export const iconClasses = iconSizeClasses[size]
|
|
32
32
|
</script>
|
|
33
33
|
|
|
@@ -105,7 +105,7 @@ defineExpose({ value: inputValue })
|
|
|
105
105
|
<button
|
|
106
106
|
type="button"
|
|
107
107
|
@click="toggleVisibility()"
|
|
108
|
-
class="text-
|
|
108
|
+
class="text-fg-subtle hover:text-fg-muted focus:outline-none"
|
|
109
109
|
:aria-label="toggleAriaLabel()"
|
|
110
110
|
>
|
|
111
111
|
<svg :show="showPassword()" class="{{ iconClasses }}" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
@@ -122,10 +122,10 @@ defineExpose({ value: inputValue })
|
|
|
122
122
|
@if(showStrength)
|
|
123
123
|
<div :show="inputValue().length > 0" class="mt-2">
|
|
124
124
|
<div class="flex items-center justify-between mb-1">
|
|
125
|
-
<span class="text-xs text-
|
|
125
|
+
<span class="text-xs text-fg-muted">Password strength</span>
|
|
126
126
|
<span class="text-xs font-medium" :class="strengthLabelColor()" x-text="strengthText()"></span>
|
|
127
127
|
</div>
|
|
128
|
-
<div class="w-full h-1.5 bg-
|
|
128
|
+
<div class="w-full h-1.5 bg-surface-sunken rounded-full overflow-hidden">
|
|
129
129
|
<div
|
|
130
130
|
class="h-full transition-all duration-300 rounded-full"
|
|
131
131
|
:class="strengthColor()"
|
|
@@ -33,25 +33,25 @@ function onDelete(methodId) {
|
|
|
33
33
|
<div class="{{ containerClasses }}">
|
|
34
34
|
@if(isLoading)
|
|
35
35
|
<div class="animate-pulse">
|
|
36
|
-
<div class="h-24 bg-
|
|
36
|
+
<div class="h-24 bg-surface-sunken rounded-lg"></div>
|
|
37
37
|
</div>
|
|
38
38
|
@else
|
|
39
39
|
@if(paymentMethods.length > 0)
|
|
40
40
|
<ul role="list" class="grid grid-cols-1 gap-6 lg:grid-cols-1 sm:grid-cols-1">
|
|
41
41
|
@foreach(method in paymentMethods)
|
|
42
|
-
<li class="col-span-1 border border-
|
|
42
|
+
<li class="col-span-1 border border-line rounded-lg bg-white dark:bg-blue-gray-800 shadow divide-y divide-line">
|
|
43
43
|
<div class="w-full p-3">
|
|
44
44
|
<div class="flex items-center justify-between">
|
|
45
45
|
<div class="flex items-center space-x-4">
|
|
46
|
-
<div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-
|
|
46
|
+
<div class="flex-shrink-0 h-10 w-10 flex items-center justify-center bg-surface-raised rounded-md">
|
|
47
47
|
<span class="text-2xl">{{ brandIcons[method.brand.toLowerCase()] || brandIcons.default }}</span>
|
|
48
48
|
</div>
|
|
49
49
|
|
|
50
50
|
<div>
|
|
51
|
-
<h2 class="text-sm text-
|
|
51
|
+
<h2 class="text-sm text-fg-muted">
|
|
52
52
|
{{ method.brand }} •••• {{ method.last_four }}
|
|
53
53
|
</h2>
|
|
54
|
-
<span class="text-xs text-
|
|
54
|
+
<span class="text-xs text-fg-soft italic">
|
|
55
55
|
Expires {{ method.exp_month }} / {{ method.exp_year }}
|
|
56
56
|
</span>
|
|
57
57
|
</div>
|
|
@@ -61,7 +61,7 @@ function onDelete(methodId) {
|
|
|
61
61
|
@if(showMakeDefault)
|
|
62
62
|
<button
|
|
63
63
|
type="button"
|
|
64
|
-
class="border border-
|
|
64
|
+
class="border border-line-strong rounded-md bg-white dark:bg-blue-gray-700 px-2 py-1 text-sm text-fg-strong font-semibold shadow-sm hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:outline-2 focus-visible:outline-blue-600 focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
65
65
|
@click="onMakeDefault('{{ method.id }}')"
|
|
66
66
|
title="Make default"
|
|
67
67
|
>
|
|
@@ -74,7 +74,7 @@ function onDelete(methodId) {
|
|
|
74
74
|
@if(showDelete)
|
|
75
75
|
<button
|
|
76
76
|
type="button"
|
|
77
|
-
class="border border-
|
|
77
|
+
class="border border-line-strong rounded-md bg-white dark:bg-blue-gray-700 px-2 py-1 text-sm text-danger font-semibold shadow-sm hover:bg-red-50 dark:hover:bg-red-900/20 focus-visible:outline-2 focus-visible:outline-red-600 focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed"
|
|
78
78
|
@click="onDelete('{{ method.id }}')"
|
|
79
79
|
title="Delete payment method"
|
|
80
80
|
>
|
|
@@ -90,12 +90,12 @@ function onDelete(methodId) {
|
|
|
90
90
|
@endforeach
|
|
91
91
|
</ul>
|
|
92
92
|
@else
|
|
93
|
-
<div class="text-center py-12 bg-white dark:bg-blue-gray-800 rounded-lg border border-
|
|
94
|
-
<svg class="mx-auto h-12 w-12 text-
|
|
93
|
+
<div class="text-center py-12 bg-white dark:bg-blue-gray-800 rounded-lg border border-line">
|
|
94
|
+
<svg class="mx-auto h-12 w-12 text-fg-subtle" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
95
95
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
|
|
96
96
|
</svg>
|
|
97
|
-
<h3 class="mt-2 text-sm text-
|
|
98
|
-
<p class="mt-1 text-sm text-
|
|
97
|
+
<h3 class="mt-2 text-sm text-fg font-medium">No payment methods</h3>
|
|
98
|
+
<p class="mt-1 text-sm text-fg-soft">
|
|
99
99
|
You haven't added any payment methods yet.
|
|
100
100
|
</p>
|
|
101
101
|
</div>
|
|
@@ -11,11 +11,11 @@ export const className = $props.className || ''
|
|
|
11
11
|
const linearSizeClasses = { sm: 'h-1', md: 'h-2', lg: 'h-3' }
|
|
12
12
|
const circularSizeClasses = { sm: 'w-12 h-12', md: 'w-16 h-16', lg: 'w-24 h-24' }
|
|
13
13
|
const colorClasses = {
|
|
14
|
-
primary: 'bg-
|
|
14
|
+
primary: 'bg-info-solid',
|
|
15
15
|
secondary: 'bg-purple-600 dark:bg-purple-500',
|
|
16
|
-
success: 'bg-
|
|
16
|
+
success: 'bg-success-solid',
|
|
17
17
|
warning: 'bg-yellow-600 dark:bg-yellow-500',
|
|
18
|
-
danger: 'bg-
|
|
18
|
+
danger: 'bg-danger-solid',
|
|
19
19
|
info: 'bg-cyan-600 dark:bg-cyan-500',
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -28,16 +28,16 @@ export const containerClasses = variant === 'linear'
|
|
|
28
28
|
? `w-full ${className}`.trim()
|
|
29
29
|
: `inline-flex items-center justify-center ${className}`.trim()
|
|
30
30
|
|
|
31
|
-
export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-
|
|
31
|
+
export const linearTrackClasses = `w-full ${linearSizeClasses[size]} bg-surface-sunken rounded-full overflow-hidden`.trim()
|
|
32
32
|
export const linearBarClasses = `h-full ${colorClasses[color]} transition-all duration-300 ease-in-out ${indeterminate ? 'animate-progress-indeterminate' : ''}`.trim()
|
|
33
33
|
export const circularSizeClass = circularSizeClasses[size]
|
|
34
|
-
export const labelClasses = `text-sm font-medium text-
|
|
34
|
+
export const labelClasses = `text-sm font-medium text-fg-strong mb-2`.trim()
|
|
35
35
|
export const circularTrackColor = 'stroke-gray-200 dark:stroke-gray-700'
|
|
36
|
-
export const circularBarColor = color === 'primary' ? 'stroke-
|
|
36
|
+
export const circularBarColor = color === 'primary' ? 'stroke-info'
|
|
37
37
|
: color === 'secondary' ? 'stroke-purple-600 dark:stroke-purple-500'
|
|
38
|
-
: color === 'success' ? 'stroke-
|
|
38
|
+
: color === 'success' ? 'stroke-success'
|
|
39
39
|
: color === 'warning' ? 'stroke-yellow-600 dark:stroke-yellow-500'
|
|
40
|
-
: color === 'danger' ? 'stroke-
|
|
40
|
+
: color === 'danger' ? 'stroke-danger'
|
|
41
41
|
: 'stroke-cyan-600 dark:stroke-cyan-500'
|
|
42
42
|
</script>
|
|
43
43
|
|
|
@@ -112,7 +112,7 @@ defineExpose({ value, setValue: (v) => value.set(v) })
|
|
|
112
112
|
|
|
113
113
|
@if(showLabel)
|
|
114
114
|
<div class="absolute inset-0 flex items-center justify-center">
|
|
115
|
-
<span class="text-sm font-semibold text-
|
|
115
|
+
<span class="text-sm font-semibold text-fg-strong" x-text="percentLabel()"></span>
|
|
116
116
|
</div>
|
|
117
117
|
@endif
|
|
118
118
|
</div>
|
|
@@ -11,13 +11,13 @@ export const name = $props.name || ''
|
|
|
11
11
|
export const className = $props.className || ''
|
|
12
12
|
|
|
13
13
|
const sizeClasses = { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6' }
|
|
14
|
-
const baseClasses = 'border-
|
|
15
|
-
const stateClasses = error ? 'border-red-300 dark:border-red-600 text-
|
|
14
|
+
const baseClasses = 'border-line-strong text-accent focus:ring-accent focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 transition-colors'
|
|
15
|
+
const stateClasses = error ? 'border-red-300 dark:border-red-600 text-danger focus:ring-red-500 dark:focus:ring-red-400' : ''
|
|
16
16
|
const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'
|
|
17
17
|
|
|
18
18
|
export const radioClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses}`.trim()
|
|
19
|
-
export const labelClasses = `text-sm font-medium ${error ? 'text-
|
|
20
|
-
export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-
|
|
19
|
+
export const labelClasses = `text-sm font-medium ${error ? 'text-danger' : 'text-fg'} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`.trim()
|
|
20
|
+
export const descriptionClasses = `text-sm ${error ? 'text-red-500 dark:text-red-400' : 'text-fg-soft'}`.trim()
|
|
21
21
|
export const inputId = `radio-${value || label}`
|
|
22
22
|
</script>
|
|
23
23
|
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<script server>
|
|
2
|
+
export const value = $props.value
|
|
3
|
+
export const className = $props.className || ''
|
|
4
|
+
export const as = $props.as || 'div'
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Prop-array mode, alongside the slot API (stacksjs/stx#1930).
|
|
8
|
+
*
|
|
9
|
+
* `<RadioGroup :options="[{ label: 'A', value: 'a' }]" />` used to emit a
|
|
10
|
+
* hydration shell and nothing else: the labels reached the page only inside
|
|
11
|
+
* `data-stx-props`, so the choices were invisible without JavaScript and to a
|
|
12
|
+
* crawler. Every comparable component here — Tabs, Accordion, Select, Navigator,
|
|
13
|
+
* Breadcrumb — server-renders its content from a prop array, so this was the
|
|
14
|
+
* odd one out rather than a deliberate choice.
|
|
15
|
+
*
|
|
16
|
+
* The options are rendered here rather than delegated to <RadioGroupOption>
|
|
17
|
+
* because a loop variable cannot cross a component boundary as a `:` binding.
|
|
18
|
+
* Interpolating it would stringify the value — `1` and `"1"` would stop being
|
|
19
|
+
* distinguishable — and the group compares values by identity. Emitting the
|
|
20
|
+
* option markup directly keeps `data-option-value` exact JSON, which is what
|
|
21
|
+
* `syncOptionStates` already reads.
|
|
22
|
+
*/
|
|
23
|
+
export const options = Array.isArray($props.options) ? $props.options : []
|
|
24
|
+
export const hasPropOptions = options.length > 0
|
|
25
|
+
|
|
26
|
+
const optionBaseClasses = 'relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none transition-all bg-white dark:bg-neutral-800 text-fg focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-60 focus-visible:ring-offset-2 focus-visible:ring-offset-blue-300 dark:focus-visible:ring-offset-blue-700'
|
|
27
|
+
export const optionClasses = optionBaseClasses
|
|
28
|
+
export const optionDisabledClasses = `${optionBaseClasses} opacity-50 cursor-not-allowed`
|
|
29
|
+
|
|
30
|
+
const baseClasses = 'w-full'
|
|
31
|
+
export const groupClasses = `${baseClasses} ${className}`.trim()
|
|
32
|
+
export const radioGroupInstanceId = `stx-rg-${Math.random().toString(36).slice(2, 11)}`
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<script client>
|
|
36
|
+
const emit = defineEmits()
|
|
37
|
+
const radioGroupInstanceId = {{ radioGroupInstanceId }}
|
|
38
|
+
const initialValue = {{ value === undefined ? 'null' : value }}
|
|
39
|
+
const selected = state(initialValue)
|
|
40
|
+
let rootEl = null
|
|
41
|
+
|
|
42
|
+
function selectValue(v) {
|
|
43
|
+
selected.set(v)
|
|
44
|
+
syncOptionStates()
|
|
45
|
+
emit('change', v)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function syncOptionStates() {
|
|
49
|
+
if (!rootEl) return
|
|
50
|
+
const options = rootEl.querySelectorAll('[data-stx-radio-option]')
|
|
51
|
+
for (const opt of options) {
|
|
52
|
+
const raw = opt.dataset.optionValue
|
|
53
|
+
let v
|
|
54
|
+
try { v = JSON.parse(raw ?? 'null') }
|
|
55
|
+
catch { v = raw }
|
|
56
|
+
const checked = selected() === v
|
|
57
|
+
opt.setAttribute('aria-checked', checked ? 'true' : 'false')
|
|
58
|
+
opt.setAttribute('data-checked', checked ? 'true' : 'false')
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function onSelect(event) {
|
|
63
|
+
event.stopPropagation()
|
|
64
|
+
selectValue(event.detail)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Options rendered from the `options` prop have no <RadioGroupOption> behind
|
|
68
|
+
// them to dispatch stx:radio-select, so the group claims them by delegation.
|
|
69
|
+
// One listener on the root rather than a handler per option, which also means
|
|
70
|
+
// options added later are picked up with no re-binding.
|
|
71
|
+
function optionValueOf(el) {
|
|
72
|
+
try { return JSON.parse(el.dataset.optionValue ?? 'null') }
|
|
73
|
+
catch { return el.dataset.optionValue }
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function onDelegatedActivate(event) {
|
|
77
|
+
const option = event.target.closest?.('[data-stx-radio-option]')
|
|
78
|
+
if (!option || !rootEl || !rootEl.contains(option)) return
|
|
79
|
+
if (option.getAttribute('aria-disabled') === 'true') return
|
|
80
|
+
// A <RadioGroupOption> dispatches its own event; claiming its click too would
|
|
81
|
+
// select twice and emit two change events.
|
|
82
|
+
if (option.dataset.stxRadioDelegated !== 'true') return
|
|
83
|
+
if (event.type === 'keydown' && event.key !== ' ' && event.key !== 'Enter') return
|
|
84
|
+
event.preventDefault()
|
|
85
|
+
selectValue(optionValueOf(option))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
onMount(() => {
|
|
89
|
+
rootEl = document.querySelector(`[data-radio-group-id="${radioGroupInstanceId}"]`)
|
|
90
|
+
if (rootEl) {
|
|
91
|
+
rootEl.addEventListener('click', onDelegatedActivate)
|
|
92
|
+
rootEl.addEventListener('keydown', onDelegatedActivate)
|
|
93
|
+
}
|
|
94
|
+
syncOptionStates()
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
onDestroy(() => {
|
|
98
|
+
if (!rootEl) return
|
|
99
|
+
rootEl.removeEventListener('click', onDelegatedActivate)
|
|
100
|
+
rootEl.removeEventListener('keydown', onDelegatedActivate)
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
defineExpose({ selected, selectValue })
|
|
104
|
+
</script>
|
|
105
|
+
|
|
106
|
+
<component
|
|
107
|
+
:is="{{ as }}"
|
|
108
|
+
class="{{ groupClasses }}"
|
|
109
|
+
data-stx-radio-group
|
|
110
|
+
data-radio-group-id="{{ radioGroupInstanceId }}"
|
|
111
|
+
role="radiogroup"
|
|
112
|
+
@stx:radio-select="onSelect($event)"
|
|
113
|
+
>
|
|
114
|
+
@if(hasPropOptions)
|
|
115
|
+
@foreach(option in options)
|
|
116
|
+
<div
|
|
117
|
+
data-stx-radio-option
|
|
118
|
+
data-stx-radio-delegated="true"
|
|
119
|
+
data-option-value="{{ JSON.stringify(option.value === undefined ? null : option.value) }}"
|
|
120
|
+
role="radio"
|
|
121
|
+
aria-checked="{{ option.value === value ? 'true' : 'false' }}"
|
|
122
|
+
data-checked="{{ option.value === value ? 'true' : 'false' }}"
|
|
123
|
+
aria-disabled="{{ option.disabled ? 'true' : 'false' }}"
|
|
124
|
+
tabindex="{{ option.disabled ? '-1' : '0' }}"
|
|
125
|
+
class="{{ option.disabled ? optionDisabledClasses : optionClasses }}"
|
|
126
|
+
>
|
|
127
|
+
<span class="flex flex-col">
|
|
128
|
+
<span class="text-sm font-medium">{{ option.label }}</span>
|
|
129
|
+
@if(option.description)
|
|
130
|
+
<span class="text-sm opacity-70">{{ option.description }}</span>
|
|
131
|
+
@endif
|
|
132
|
+
</span>
|
|
133
|
+
</div>
|
|
134
|
+
@endforeach
|
|
135
|
+
@else
|
|
136
|
+
<slot />
|
|
137
|
+
@endif
|
|
138
|
+
</component>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export const className = $props.className || ''
|
|
3
3
|
export const as = $props.as || 'span'
|
|
4
4
|
|
|
5
|
-
const baseClasses = 'inline text-sm text-
|
|
5
|
+
const baseClasses = 'inline text-sm text-fg-soft'
|
|
6
6
|
const descriptionClasses = `${baseClasses} ${className}`.trim()
|
|
7
7
|
</script>
|
|
8
8
|
|
|
@@ -4,7 +4,7 @@ export const disabled = $props.disabled || false
|
|
|
4
4
|
export const className = $props.className || ''
|
|
5
5
|
export const as = $props.as || 'div'
|
|
6
6
|
|
|
7
|
-
const baseClasses = 'relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none transition-all bg-white dark:bg-neutral-800 text-
|
|
7
|
+
const baseClasses = 'relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none transition-all bg-white dark:bg-neutral-800 text-fg focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-60 focus-visible:ring-offset-2 focus-visible:ring-offset-blue-300 dark:focus-visible:ring-offset-blue-700'
|
|
8
8
|
const disabledClasses = disabled ? 'opacity-50 cursor-not-allowed' : ''
|
|
9
9
|
export const optionClasses = `${baseClasses} ${disabledClasses} ${className}`.trim()
|
|
10
10
|
export const valueJson = JSON.stringify(value === undefined ? null : value)
|
|
@@ -14,14 +14,14 @@ const sizeClasses = { sm: 'px-3 py-1.5 text-sm h-8', md: 'px-4 py-2 text-base h-
|
|
|
14
14
|
const baseClasses = 'block w-full border-0 rounded-md shadow-sm ring-1 ring-inset transition-colors duration-200 focus:ring-2 focus:ring-inset dark:bg-blue-gray-700 dark:text-gray-100'
|
|
15
15
|
const stateClasses = error
|
|
16
16
|
? 'ring-red-300 dark:ring-red-600 text-red-900 dark:text-red-300 placeholder-red-300 dark:placeholder-red-500 focus:ring-red-500 dark:focus:ring-red-400'
|
|
17
|
-
: 'ring-
|
|
17
|
+
: 'ring-line-strong text-fg placeholder-fg-subtle focus:ring-accent'
|
|
18
18
|
const disabledClasses = disabled
|
|
19
|
-
? 'opacity-50 cursor-not-allowed bg-
|
|
19
|
+
? 'opacity-50 cursor-not-allowed bg-surface'
|
|
20
20
|
: 'bg-white dark:bg-blue-gray-700 cursor-pointer hover:ring-gray-400 dark:hover:ring-gray-500'
|
|
21
21
|
|
|
22
22
|
export const selectClasses = `${baseClasses} ${sizeClasses[size]} ${stateClasses} ${disabledClasses} ${className}`.trim()
|
|
23
|
-
export const labelClasses = `block text-sm font-medium leading-6 ${error ? 'text-
|
|
24
|
-
export const helperClasses = `mt-2 text-sm ${error ? 'text-
|
|
23
|
+
export const labelClasses = `block text-sm font-medium leading-6 ${error ? 'text-danger' : 'text-fg'}`.trim()
|
|
24
|
+
export const helperClasses = `mt-2 text-sm ${error ? 'text-danger' : 'text-fg-soft'}`.trim()
|
|
25
25
|
export const selectId = `select-${value}`
|
|
26
26
|
</script>
|
|
27
27
|
|
|
@@ -53,7 +53,7 @@ export const isLink = Boolean(href) && !disabled
|
|
|
53
53
|
@if(indentStyle)style="{{ indentStyle }}"@endif
|
|
54
54
|
>
|
|
55
55
|
@if(isLink)
|
|
56
|
-
<
|
|
56
|
+
<StxLink to="{{ href }}" data-sidebar-item data-label="{{ label }}" class="{{ rowClasses }}" :data-active="active ? 'true' : null" :aria-current="active ? 'page' : null">
|
|
57
57
|
<span class="{{ disclosureClasses }}" @if(expandable)data-sidebar-disclosure role="button" aria-label="Toggle {{ label }}"@endif>
|
|
58
58
|
@if(expandable)
|
|
59
59
|
<span data-sidebar-chevron class="{{ chevronClasses }}" aria-hidden="true"></span>
|
|
@@ -68,7 +68,7 @@ export const isLink = Boolean(href) && !disabled
|
|
|
68
68
|
@if(count !== '' && count !== null && count !== undefined)
|
|
69
69
|
<span data-sidebar-count class="{{ countClasses }}">{{ count }}</span>
|
|
70
70
|
@endif
|
|
71
|
-
</
|
|
71
|
+
</StxLink>
|
|
72
72
|
@else
|
|
73
73
|
<button type="button" data-sidebar-item data-label="{{ label }}" class="{{ rowClasses }}" @if(active)data-active="true" aria-current="page"@endif @if(disabled)data-disabled disabled aria-disabled="true"@endif>
|
|
74
74
|
<span class="{{ disclosureClasses }}" @if(expandable)data-sidebar-disclosure role="button" aria-label="Toggle {{ label }}"@endif>
|
|
@@ -51,8 +51,8 @@ function onPinnedClick(event) {
|
|
|
51
51
|
>
|
|
52
52
|
@foreach(items as item)
|
|
53
53
|
@if(item.href)
|
|
54
|
-
<
|
|
55
|
-
|
|
54
|
+
<StxLink
|
|
55
|
+
to="{{ item.href }}"
|
|
56
56
|
data-space-pinned-item
|
|
57
57
|
data-pinned-id="{{ item.id }}"
|
|
58
58
|
class="{{ tileClasses }}"
|
|
@@ -65,7 +65,7 @@ function onPinnedClick(event) {
|
|
|
65
65
|
@else
|
|
66
66
|
<span class="{{ item.icon }} h-[20px] w-[20px]" @if(item.iconStyle)style="{{ item.iconStyle }}"@endif aria-hidden="true"></span>
|
|
67
67
|
@endif
|
|
68
|
-
</
|
|
68
|
+
</StxLink>
|
|
69
69
|
@else
|
|
70
70
|
<button
|
|
71
71
|
type="button"
|
|
@@ -9,6 +9,14 @@ export const containerClasses = `min-h-full flex flex-col justify-center py-12 l
|
|
|
9
9
|
<script client>
|
|
10
10
|
const emit = defineEmits()
|
|
11
11
|
|
|
12
|
+
// The social buttons used to be `<a href="#">` — a link that navigates
|
|
13
|
+
// nowhere and that a host app had no way to wire (#1930). They are not
|
|
14
|
+
// navigation, so they are real buttons now, and the provider is emitted so
|
|
15
|
+
// the app can start its own OAuth flow.
|
|
16
|
+
function onSocial(provider) {
|
|
17
|
+
emit('social', { provider })
|
|
18
|
+
}
|
|
19
|
+
|
|
12
20
|
function onSubmit(event) {
|
|
13
21
|
event.preventDefault()
|
|
14
22
|
const formData = new FormData(event.target)
|
|
@@ -33,7 +41,7 @@ function onSubmit(event) {
|
|
|
33
41
|
|
|
34
42
|
<div class="{{ containerClasses }}">
|
|
35
43
|
<div class="sm:mx-auto sm:max-w-md sm:w-full">
|
|
36
|
-
<h2 class="mt-6 text-center text-2xl text-
|
|
44
|
+
<h2 class="mt-6 text-center text-2xl text-fg font-bold leading-9 tracking-tight">
|
|
37
45
|
{{ headingText }}
|
|
38
46
|
</h2>
|
|
39
47
|
</div>
|
|
@@ -42,7 +50,7 @@ function onSubmit(event) {
|
|
|
42
50
|
<div class="bg-white dark:bg-blue-gray-800 px-6 py-12 shadow sm:rounded-lg sm:px-12">
|
|
43
51
|
<form class="space-y-6" @submit="onSubmit($event)">
|
|
44
52
|
<div>
|
|
45
|
-
<label for="name" class="block text-sm text-
|
|
53
|
+
<label for="name" class="block text-sm text-fg font-medium leading-6">
|
|
46
54
|
Full Name
|
|
47
55
|
</label>
|
|
48
56
|
<div class="mt-2">
|
|
@@ -52,13 +60,13 @@ function onSubmit(event) {
|
|
|
52
60
|
type="text"
|
|
53
61
|
autocomplete="name"
|
|
54
62
|
required
|
|
55
|
-
class="block w-full border-0 rounded-md p-2 py-1.5 text-
|
|
63
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-fg shadow-sm ring-1 ring-line-strong ring-inset sm:text-sm placeholder:text-fg-subtle sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
56
64
|
/>
|
|
57
65
|
</div>
|
|
58
66
|
</div>
|
|
59
67
|
|
|
60
68
|
<div>
|
|
61
|
-
<label for="email" class="block text-sm text-
|
|
69
|
+
<label for="email" class="block text-sm text-fg font-medium leading-6">
|
|
62
70
|
Email address
|
|
63
71
|
</label>
|
|
64
72
|
<div class="mt-2">
|
|
@@ -68,13 +76,13 @@ function onSubmit(event) {
|
|
|
68
76
|
type="email"
|
|
69
77
|
autocomplete="email"
|
|
70
78
|
required
|
|
71
|
-
class="block w-full border-0 rounded-md p-2 py-1.5 text-
|
|
79
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-fg shadow-sm ring-1 ring-line-strong ring-inset sm:text-sm placeholder:text-fg-subtle sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
72
80
|
/>
|
|
73
81
|
</div>
|
|
74
82
|
</div>
|
|
75
83
|
|
|
76
84
|
<div>
|
|
77
|
-
<label for="confirm_email" class="block text-sm text-
|
|
85
|
+
<label for="confirm_email" class="block text-sm text-fg font-medium leading-6">
|
|
78
86
|
Confirm Email
|
|
79
87
|
</label>
|
|
80
88
|
<div class="mt-2">
|
|
@@ -84,13 +92,13 @@ function onSubmit(event) {
|
|
|
84
92
|
type="email"
|
|
85
93
|
autocomplete="email"
|
|
86
94
|
required
|
|
87
|
-
class="block w-full border-0 rounded-md p-2 py-1.5 text-
|
|
95
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-fg shadow-sm ring-1 ring-line-strong ring-inset sm:text-sm placeholder:text-fg-subtle sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
88
96
|
/>
|
|
89
97
|
</div>
|
|
90
98
|
</div>
|
|
91
99
|
|
|
92
100
|
<div>
|
|
93
|
-
<label for="password" class="block text-sm text-
|
|
101
|
+
<label for="password" class="block text-sm text-fg font-medium leading-6">
|
|
94
102
|
Password
|
|
95
103
|
</label>
|
|
96
104
|
<div class="mt-2">
|
|
@@ -100,7 +108,7 @@ function onSubmit(event) {
|
|
|
100
108
|
type="password"
|
|
101
109
|
autocomplete="new-password"
|
|
102
110
|
required
|
|
103
|
-
class="block w-full border-0 rounded-md p-2 py-1.5 text-
|
|
111
|
+
class="block w-full border-0 rounded-md p-2 py-1.5 text-fg shadow-sm ring-1 ring-line-strong ring-inset sm:text-sm placeholder:text-fg-subtle sm:leading-6 focus:ring-2 focus:ring-teal-600 focus:ring-inset dark:bg-blue-gray-700"
|
|
104
112
|
/>
|
|
105
113
|
</div>
|
|
106
114
|
</div>
|
|
@@ -119,19 +127,20 @@ function onSubmit(event) {
|
|
|
119
127
|
<div>
|
|
120
128
|
<div class="relative mt-10">
|
|
121
129
|
<div class="absolute inset-0 flex items-center" aria-hidden="true">
|
|
122
|
-
<div class="w-full border-t border-
|
|
130
|
+
<div class="w-full border-t border-line"></div>
|
|
123
131
|
</div>
|
|
124
132
|
<div class="relative flex justify-center text-sm font-medium leading-6">
|
|
125
|
-
<span class="bg-white dark:bg-blue-gray-800 px-6 text-
|
|
133
|
+
<span class="bg-white dark:bg-blue-gray-800 px-6 text-fg">
|
|
126
134
|
Or signup with
|
|
127
135
|
</span>
|
|
128
136
|
</div>
|
|
129
137
|
</div>
|
|
130
138
|
|
|
131
139
|
<div class="grid grid-cols-2 mt-6 gap-4">
|
|
132
|
-
<
|
|
133
|
-
|
|
134
|
-
|
|
140
|
+
<button
|
|
141
|
+
type="button"
|
|
142
|
+
@click="onSocial('google')"
|
|
143
|
+
class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-fg font-semibold shadow-sm ring-1 ring-line-strong ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
|
|
135
144
|
>
|
|
136
145
|
<svg class="h-5 w-5" viewBox="0 0 24 24" aria-hidden="true">
|
|
137
146
|
<path d="M12.0003 4.75C13.7703 4.75 15.3553 5.36002 16.6053 6.54998L20.0303 3.125C17.9502 1.19 15.2353 0 12.0003 0C7.31028 0 3.25527 2.69 1.28027 6.60998L5.27028 9.70498C6.21525 6.86002 8.87028 4.75 12.0003 4.75Z" fill="#EA4335" />
|
|
@@ -140,17 +149,18 @@ function onSubmit(event) {
|
|
|
140
149
|
<path d="M12.0004 24.0001C15.2404 24.0001 17.9654 22.935 19.9454 21.095L16.0804 18.095C15.0054 18.82 13.6204 19.245 12.0004 19.245C8.8704 19.245 6.21537 17.135 5.2654 14.29L1.27539 17.385C3.25539 21.31 7.3104 24.0001 12.0004 24.0001Z" fill="#34A853" />
|
|
141
150
|
</svg>
|
|
142
151
|
<span class="text-sm font-semibold leading-6">Google</span>
|
|
143
|
-
</
|
|
152
|
+
</button>
|
|
144
153
|
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
154
|
+
<button
|
|
155
|
+
type="button"
|
|
156
|
+
@click="onSocial('github')"
|
|
157
|
+
class="w-full flex items-center justify-center gap-3 rounded-md bg-white dark:bg-blue-gray-700 px-3 py-2 text-sm text-fg font-semibold shadow-sm ring-1 ring-line-strong ring-inset hover:bg-gray-50 dark:hover:bg-blue-gray-600 focus-visible:ring-transparent"
|
|
148
158
|
>
|
|
149
159
|
<svg class="h-5 w-5 fill-[#24292F] dark:fill-white" fill="currentColor" viewBox="0 0 20 20" aria-hidden="true">
|
|
150
160
|
<path fill-rule="evenodd" d="M10 0C4.477 0 0 4.484 0 10.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0110 4.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.203 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0020 10.017C20 4.484 15.522 0 10 0z" clip-rule="evenodd" />
|
|
151
161
|
</svg>
|
|
152
162
|
<span class="text-sm font-semibold leading-6">GitHub</span>
|
|
153
|
-
</
|
|
163
|
+
</button>
|
|
154
164
|
</div>
|
|
155
165
|
</div>
|
|
156
166
|
@endif
|
|
@@ -33,7 +33,7 @@ if (height) {
|
|
|
33
33
|
styleString += `height: ${typeof height === 'number' ? height + 'px' : height};`
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export const skeletonClasses = `bg-
|
|
36
|
+
export const skeletonClasses = `bg-surface-sunken ${baseClasses} ${animationClasses} ${className}`.trim()
|
|
37
37
|
export const containerClasses = count > 1 ? 'space-y-3' : ''
|
|
38
38
|
</script>
|
|
39
39
|
|