@1001-digital/layers.base 0.0.1

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.
Files changed (55) hide show
  1. package/.editorconfig +12 -0
  2. package/.nuxtrc +1 -0
  3. package/.playground/app.config.ts +5 -0
  4. package/.playground/app.vue +3 -0
  5. package/.playground/nuxt.config.ts +12 -0
  6. package/.playground/pages/index.vue +626 -0
  7. package/AGENTS.md +51 -0
  8. package/README.md +13 -0
  9. package/app/app.vue +3 -0
  10. package/app/assets/styles/base/base.css +52 -0
  11. package/app/assets/styles/base/forms.css +129 -0
  12. package/app/assets/styles/base/reset.css +159 -0
  13. package/app/assets/styles/index.css +28 -0
  14. package/app/assets/styles/utilities/animations.css +77 -0
  15. package/app/assets/styles/utilities/utilities.css +58 -0
  16. package/app/assets/styles/variables/borders.css +18 -0
  17. package/app/assets/styles/variables/colors.css +75 -0
  18. package/app/assets/styles/variables/components/alerts.css +13 -0
  19. package/app/assets/styles/variables/components/buttons.css +18 -0
  20. package/app/assets/styles/variables/components/cards.css +7 -0
  21. package/app/assets/styles/variables/components/dialogs.css +7 -0
  22. package/app/assets/styles/variables/components/forms.css +5 -0
  23. package/app/assets/styles/variables/components/images.css +5 -0
  24. package/app/assets/styles/variables/components/index.css +6 -0
  25. package/app/assets/styles/variables/effects.css +3 -0
  26. package/app/assets/styles/variables/fonts.css +36 -0
  27. package/app/assets/styles/variables/index.css +15 -0
  28. package/app/assets/styles/variables/layout.css +7 -0
  29. package/app/assets/styles/variables/sizes.css +24 -0
  30. package/app/assets/styles/variables/timing.css +5 -0
  31. package/app/assets/styles/variables/ui.css +18 -0
  32. package/app/assets/styles/variables/z-index.css +7 -0
  33. package/app/components/Actions.vue +57 -0
  34. package/app/components/Alert.vue +78 -0
  35. package/app/components/Button.vue +196 -0
  36. package/app/components/Card.vue +62 -0
  37. package/app/components/Dialog.client.vue +217 -0
  38. package/app/components/Form/Form.vue +27 -0
  39. package/app/components/Form/FormCheckbox.vue +88 -0
  40. package/app/components/Form/FormGroup.vue +36 -0
  41. package/app/components/Form/FormInputGroup.vue +55 -0
  42. package/app/components/Form/FormItem.vue +53 -0
  43. package/app/components/Form/FormLabel.vue +39 -0
  44. package/app/components/Form/FormRadioGroup.vue +109 -0
  45. package/app/components/Form/FormSelect.vue +155 -0
  46. package/app/components/HelloWorld.vue +10 -0
  47. package/app/components/Icon.vue +48 -0
  48. package/app/components/Loading.vue +58 -0
  49. package/app/components/Tag.vue +47 -0
  50. package/app/components/Tags.vue +13 -0
  51. package/app.config.ts +14 -0
  52. package/eslint.config.js +3 -0
  53. package/nuxt.config.ts +19 -0
  54. package/package.json +29 -0
  55. package/tsconfig.json +3 -0
@@ -0,0 +1,7 @@
1
+ :root {
2
+ --dialog-initial-x-offset: 0;
3
+ --dialog-initial-y-offset: var(--spacer);
4
+ --dialog-x-offset: 0;
5
+ --dialog-y-offset: 0;
6
+ --backdrop-background-color: transparent;
7
+ }
@@ -0,0 +1,5 @@
1
+ :root {
2
+ --form-item-height: calc(var(--size-4) + var(--ui-padding-block) * 2);
3
+ --form-item-height-sm: calc(var(--size-4) + var(--ui-padding-block));
4
+ --input-text-transform: none;
5
+ }
@@ -0,0 +1,5 @@
1
+ :root {
2
+ --image-border-radius: var(--size-1);
3
+ --image-border: var(--border);
4
+ --image-loading-background: var(--gray-z-0);
5
+ }
@@ -0,0 +1,6 @@
1
+ @import './alerts.css';
2
+ @import './buttons.css';
3
+ @import './cards.css';
4
+ @import './dialogs.css';
5
+ @import './forms.css';
6
+ @import './images.css';
@@ -0,0 +1,3 @@
1
+ :root {
2
+ --blur: blur(var(--size-1));
3
+ }
@@ -0,0 +1,36 @@
1
+ :root {
2
+ --rem: 16px;
3
+
4
+ /* Font families */
5
+ --font-family: sans-serif;
6
+ --font-family-serif: serif;
7
+
8
+ /* Fluid font sizes using clamp(min, preferred, max) */
9
+ --font-base: clamp(0.9375rem, 0.875rem + 0.25vw, 1.0625rem);
10
+ --font-xs: clamp(0.625rem, 0.6rem + 0.15vw, 0.75rem);
11
+ --font-sm: clamp(0.75rem, 0.7rem + 0.2vw, 0.875rem);
12
+ --font-lg: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
13
+ --font-xl: clamp(1.375rem, 1.2rem + 0.75vw, 1.75rem);
14
+ --font-2xl: clamp(1.75rem, 1.5rem + 1vw, 2.25rem);
15
+ --font-3xl: clamp(2.25rem, 1.8rem + 1.5vw, 3rem);
16
+
17
+ /* Font weights */
18
+ --font-weight-light: 300;
19
+ --font-weight: 400;
20
+ --font-weight-bold: 500;
21
+
22
+ /* Letter spacing */
23
+ --letter-spacing-sm: -0.025em;
24
+ --letter-spacing: 0.025em;
25
+ --letter-spacing-md: 0.05em;
26
+ --letter-spacing-lg: 0.1em;
27
+
28
+ /* Line heights */
29
+ --line-height-sm: 105%;
30
+ --line-height: 100%;
31
+ --line-height-md: 120%;
32
+ --line-height-lg: 160%;
33
+
34
+ /* Text transform */
35
+ --text-transform: none;
36
+ }
@@ -0,0 +1,15 @@
1
+ /*
2
+ * CSS Custom Properties
3
+ * Organized by category. Order matters as some depend on others.
4
+ */
5
+
6
+ @import './colors.css';
7
+ @import './sizes.css';
8
+ @import './fonts.css';
9
+ @import './borders.css';
10
+ @import './effects.css';
11
+ @import './timing.css';
12
+ @import './ui.css';
13
+ @import './layout.css';
14
+ @import './z-index.css';
15
+ @import './components/index.css';
@@ -0,0 +1,7 @@
1
+ :root {
2
+ --dialog-width: 27rem;
3
+ --content-width-wide: 90rem;
4
+ --content-width: 60rem;
5
+ --content-width-sm: 35rem;
6
+ --form-width: 24rem;
7
+ }
@@ -0,0 +1,24 @@
1
+ :root {
2
+ --100vh: 100dvh;
3
+
4
+ /* Size scale */
5
+ --size-0: 0.125rem;
6
+ --size-1: 0.25rem;
7
+ --size-2: 0.5rem;
8
+ --size-3: 0.75rem;
9
+ --size-4: 1rem;
10
+ --size-5: 1.25rem;
11
+ --size-6: 1.5rem;
12
+ --size-7: 2rem;
13
+ --size-8: 3rem;
14
+ --size-9: 4.5rem;
15
+ --size-10: 6rem;
16
+
17
+ /* Semantic spacers */
18
+ --spacer-xs: var(--size-0);
19
+ --spacer-sm: var(--size-2);
20
+ --spacer: var(--size-4);
21
+ --spacer-md: var(--size-6);
22
+ --spacer-lg: var(--size-7);
23
+ --spacer-xl: var(--size-9);
24
+ }
@@ -0,0 +1,5 @@
1
+ :root {
2
+ --speed-fast: 0.15s;
3
+ --speed: 0.3s;
4
+ --speed-slow: 0.75s;
5
+ }
@@ -0,0 +1,18 @@
1
+ :root {
2
+ /* UI typography */
3
+ --ui-font-family: sans-serif;
4
+ --ui-font-size: 13px;
5
+ --ui-font-weight: 400;
6
+ --ui-text-transform: uppercase;
7
+ --ui-letter-spacing: var(--letter-spacing);
8
+ --ui-line-height: var(--line-height);
9
+
10
+ /* UI colors */
11
+ --ui-color: var(--primary);
12
+ --ui-placeholder-color: var(--gray-z-5);
13
+ --ui-color-visited: var(--primary);
14
+
15
+ /* UI spacing (logical property naming) */
16
+ --ui-padding-block: var(--spacer-sm);
17
+ --ui-padding-inline: var(--spacer);
18
+ }
@@ -0,0 +1,7 @@
1
+ :root {
2
+ --z-index-n1: -1;
3
+ --z-index-0: 0;
4
+ --z-index-ui: 2;
5
+ --z-index-overlay: 9;
6
+ --z-index-dialog: 10;
7
+ }
@@ -0,0 +1,57 @@
1
+ <template>
2
+ <menu class="actions">
3
+ <slot />
4
+ </menu>
5
+ </template>
6
+
7
+ <style scoped>
8
+ .actions {
9
+ margin: 0;
10
+ padding: 0;
11
+ border: 0;
12
+ display: flex;
13
+ align-items: center;
14
+ flex-wrap: wrap;
15
+ gap: var(--spacer-sm);
16
+
17
+ &:not(.left) {
18
+ justify-content: flex-end;
19
+ }
20
+
21
+ &:empty {
22
+ display: none !important;
23
+ }
24
+
25
+ :deep(> a),
26
+ :deep(> button),
27
+ :deep(> .input-group),
28
+ :deep(> .input-group > *) {
29
+ block-size: var(--form-item-height);
30
+
31
+ &.small {
32
+ block-size: var(--form-item-height-sm);
33
+ }
34
+ }
35
+
36
+ :deep(> label) {
37
+ font-family: var(--ui-font-family);
38
+ font-size: var(--ui-font-size);
39
+ font-weight: var(--ui-font-weight);
40
+ text-transform: var(--ui-text-transform);
41
+ letter-spacing: var(--ui-letter-spacing);
42
+ line-height: var(--ui-line-height);
43
+ display: flex;
44
+ align-items: center;
45
+ gap: var(--spacer-sm);
46
+ white-space: nowrap;
47
+ }
48
+
49
+ :deep(.button) {
50
+ inline-size: auto;
51
+ }
52
+
53
+ :deep(select) {
54
+ inline-size: auto;
55
+ }
56
+ }
57
+ </style>
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <Transition name="fade">
3
+ <aside v-if="!dismissed" class="alert" :class="[type]">
4
+ <button v-if="dismissable" @click="dismiss" class="close">
5
+ <Icon type="close" />
6
+ </button>
7
+ <slot />
8
+ </aside>
9
+ </Transition>
10
+ </template>
11
+
12
+ <script setup lang="ts">
13
+ import { useLocalStorage } from '@vueuse/core'
14
+
15
+ const props = defineProps<{
16
+ type?: 'info' | 'error'
17
+ dismiss?: string
18
+ }>()
19
+
20
+ const dismissKey = computed(() => `alert:${props.dismiss}`)
21
+
22
+ const dismissed = useLocalStorage(dismissKey.value, false)
23
+ const dismissable = computed(() => !!props.dismiss)
24
+
25
+ const dismiss = () => {
26
+ dismissed.value = true
27
+ }
28
+ </script>
29
+
30
+ <style scoped>
31
+ .alert {
32
+ position: relative;
33
+ display: grid;
34
+ padding: var(--spacer-sm);
35
+ gap: var(--spacer-sm);
36
+ border: var(--border);
37
+ border-color: var(--alert-border-color);
38
+ background-color: var(--alert-background-color);
39
+ color: var(--alert-color);
40
+ font-family: var(--ui-font-family);
41
+ font-size: var(--ui-font-size);
42
+ text-transform: var(--ui-text-transform);
43
+
44
+ &.info {
45
+ border-color: var(--alert-info-border-color);
46
+ background-color: var(--alert-info-background-color);
47
+ color: var(--alert-info-color);
48
+ }
49
+
50
+ &.error {
51
+ border-color: var(--alert-error-border-color);
52
+ background-color: var(--alert-error-background-color);
53
+ color: var(--alert-error-color);
54
+ }
55
+
56
+ :deep(> h1) {
57
+ text-transform: uppercase;
58
+ font-weight: bold;
59
+ }
60
+
61
+ .close {
62
+ display: flex;
63
+ align-items: center;
64
+ justify-content: center;
65
+ position: absolute;
66
+ inline-size: var(--size-4);
67
+ block-size: var(--size-4);
68
+ padding: 0;
69
+ inset-block-start: var(--spacer-sm);
70
+ inset-inline-end: var(--spacer-sm);
71
+ background: none;
72
+
73
+ &:is(:hover, :active, :focus, .active) {
74
+ background: none;
75
+ }
76
+ }
77
+ }
78
+ </style>
@@ -0,0 +1,196 @@
1
+ <template>
2
+ <NuxtLink v-if="to" :to="to" :exact="exact" :target="target" :class="['button']">
3
+ <slot />
4
+ </NuxtLink>
5
+ <button v-else>
6
+ <slot />
7
+ </button>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import type { RouteLocationRaw } from 'vue-router'
12
+
13
+ withDefaults(defineProps<{
14
+ to?: string | RouteLocationRaw
15
+ target?: string
16
+ exact?: boolean
17
+ }>(), {
18
+ target: '_self',
19
+ })
20
+ </script>
21
+
22
+ <style scoped>
23
+ button,
24
+ a.button {
25
+ position: relative;
26
+ min-inline-size: fit-content;
27
+ inline-size: fit-content;
28
+ display: inline-flex;
29
+ justify-content: center;
30
+ align-items: center;
31
+ gap: var(--spacer-sm);
32
+
33
+ &:not(.unstyled) {
34
+ background: var(--button-background);
35
+ color: var(--button-color);
36
+ padding: var(--ui-padding-block) var(--ui-padding-inline);
37
+ border: none;
38
+ border-radius: var(--button-border-radius);
39
+ box-shadow: var(--border-shadow);
40
+ transition:
41
+ background var(--speed),
42
+ box-shadow var(--speed),
43
+ color var(--speed);
44
+ }
45
+
46
+ >span {
47
+ display: flex;
48
+ gap: var(--ui-padding-inline);
49
+ line-height: var(--ui-line-height);
50
+ justify-content: center;
51
+ text-align: center;
52
+ align-items: center;
53
+ inline-size: 100%;
54
+ block-size: 100%;
55
+ }
56
+
57
+ >.icon {
58
+ color: var(--button-icon-color);
59
+ transition: color var(--speed);
60
+ }
61
+
62
+ &:has(> .icon:first-child) {
63
+ padding-inline-start: calc(var(--ui-padding-inline) - var(--size-1));
64
+
65
+ &.small {
66
+ padding-inline-start: calc(var(--ui-padding-inline) / 2);
67
+ }
68
+ }
69
+
70
+ &:has(> .icon:first-child:last-child) {
71
+ padding: var(--ui-padding-block);
72
+ aspect-ratio: 1;
73
+
74
+ &.small {
75
+ padding: calc(var(--ui-padding-block) / 2);
76
+ }
77
+ }
78
+
79
+ &.non-interactive,
80
+ &[disabled]:not([disabled='false']) {
81
+ pointer-events: none;
82
+ }
83
+
84
+ &[disabled]:not([disabled='false']) {
85
+ color: var(--muted);
86
+ opacity: 0.5;
87
+ }
88
+
89
+ &.small {
90
+ padding: calc(var(--ui-padding-block) / 2) calc(var(--ui-padding-inline) / 2);
91
+ min-block-size: 0;
92
+
93
+ >.icon {
94
+ inline-size: var(--size-3);
95
+ block-size: var(--size-3);
96
+ }
97
+ }
98
+
99
+ &.link {
100
+ box-shadow: none;
101
+ background: transparent;
102
+ line-height: inherit;
103
+ color: var(--color);
104
+ padding: 0;
105
+
106
+ >.icon {
107
+ align-self: center;
108
+ block-size: 1em;
109
+ inline-size: 1em;
110
+ }
111
+
112
+ &.muted {
113
+ color: var(--muted);
114
+
115
+ >.icon {
116
+ color: var(--muted);
117
+ }
118
+ }
119
+ }
120
+
121
+ &.inline {
122
+ display: inline-flex;
123
+ align-self: baseline;
124
+ align-items: baseline;
125
+ block-size: inherit;
126
+ margin: 0 !important;
127
+ padding: 0 var(--size-1) !important;
128
+ gap: 0.2em;
129
+ inline-size: min-content;
130
+ }
131
+
132
+ &.invisible {
133
+ position: absolute;
134
+ inset-inline-start: -200vw;
135
+ opacity: 0;
136
+ }
137
+
138
+ &.danger {
139
+ box-shadow: 0 0 0 var(--border-width) var(--error);
140
+ color: var(--error) !important;
141
+
142
+ >.icon {
143
+ color: var(--error);
144
+ }
145
+ }
146
+
147
+ /* Primary variant */
148
+ &.primary {
149
+ background: var(--button-primary-background);
150
+ box-shadow: 0 0 0 var(--border-width) var(--button-primary-border-color);
151
+ color: var(--button-primary-color);
152
+
153
+ >.icon {
154
+ color: var(--button-primary-color);
155
+ }
156
+
157
+ &:is(:hover, :active, :focus, .active) {
158
+ background: var(--button-primary-background-highlight);
159
+ box-shadow: 0 0 0 var(--border-width) var(--button-primary-border-color-highlight);
160
+ color: var(--button-primary-color-highlight);
161
+
162
+ >.icon {
163
+ color: var(--button-primary-color-highlight);
164
+ }
165
+ }
166
+ }
167
+
168
+ &:is(:hover, :active, :focus, .active) {
169
+ background: var(--button-background-highlight);
170
+ box-shadow: var(--border-shadow-highlight);
171
+ color: var(--button-color-highlight);
172
+
173
+ >.icon {
174
+ color: var(--button-icon-color-highlight);
175
+ }
176
+
177
+ &.link {
178
+ background: transparent !important;
179
+ box-shadow: none;
180
+ color: var(--color);
181
+
182
+ >.icon {
183
+ color: var(--gray-z-7);
184
+ }
185
+
186
+ &.muted {
187
+ color: var(--color);
188
+
189
+ >.icon {
190
+ color: var(--gray-z-7);
191
+ }
192
+ }
193
+ }
194
+ }
195
+ }
196
+ </style>
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <article class="card">
3
+ <slot />
4
+ </article>
5
+ </template>
6
+
7
+ <style scoped>
8
+ .card {
9
+ display: grid;
10
+ gap: var(--spacer);
11
+ background-color: var(--card-background);
12
+ block-size: 100%;
13
+ padding: var(--spacer);
14
+ transition:
15
+ background var(--speed),
16
+ border-color var(--speed);
17
+
18
+ &:not(.borderless) {
19
+ border: var(--card-border);
20
+ border-radius: var(--card-border-radius);
21
+
22
+ &:has(> .card-link) {
23
+ &:has(> .card-link:hover),
24
+ &:has(> .card-link:focus) {
25
+ border-color: var(--card-border-color-highlight);
26
+ }
27
+ }
28
+ }
29
+
30
+ &.borderless {
31
+ padding: 0;
32
+ }
33
+
34
+ &:has(> .card-link) {
35
+ &:has(> .card-link:hover),
36
+ &:has(> .card-link:focus) {
37
+ background-color: var(--card-background-highlight);
38
+ }
39
+ }
40
+
41
+ &.static {
42
+ background-color: var(--card-background);
43
+ }
44
+
45
+ &.highlight {
46
+ background-color: var(--card-background-highlight);
47
+ }
48
+
49
+ > * {
50
+ inline-size: 100%;
51
+ place-self: center;
52
+
53
+ &:first-child {
54
+ place-self: flex-start;
55
+ }
56
+
57
+ &:last-child {
58
+ place-self: flex-end;
59
+ }
60
+ }
61
+ }
62
+ </style>