@vsn-ux/gaia-styles 0.6.7 → 0.6.8

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.
@@ -0,0 +1,77 @@
1
+ # Loader
2
+
3
+ ## Visual Structure
4
+
5
+ ### Block Loader
6
+
7
+ ```
8
+ ga-loader [--small|--medium|--large]
9
+ ├── ga-loader__icon ga-loader__icon--animated
10
+ ├── ga-loader__icon ga-loader__icon--reduced-motion
11
+ └── ga-loader__label (optional, hidden when empty)
12
+ ```
13
+
14
+ ### Inline Loader
15
+
16
+ ```
17
+ ga-inline-loading [--active|--completed|--error|--inactive]
18
+ ├── ga-inline-loading__icon (optional, displayed based on state)
19
+ └── text content
20
+ ```
21
+
22
+ ## Elements Hierarchy
23
+
24
+ ### Core Block
25
+
26
+ - `ga-loader` - Main container for the loader component. Can be combined with a size modifier.
27
+
28
+ ### Child Elements
29
+
30
+ - `ga-loader__icon` - The loading icon. Icon size is controlled by CSS based on the size modifier.
31
+ - `ga-loader__icon--animated` - Animated spinner shown by default. Use the loader SVG from `@vsn-ux/gaia-styles/images/loader.svg`.
32
+ - `ga-loader__icon--reduced-motion` - Non-animated `HourglassIcon` from `lucide-react`, shown when `prefers-reduced-motion: reduce` is active.
33
+ - `ga-loader__label` - Text displayed below the loader to provide context (optional, automatically hidden when empty)
34
+
35
+ ### Size Modifiers
36
+
37
+ - `ga-loader--small` - Small size loader
38
+ - `ga-loader--medium` - Medium size loader, default
39
+ - `ga-loader--large` - Large size loader
40
+
41
+ ## Inline Loading
42
+
43
+ ### Core Block
44
+
45
+ - `ga-inline-loading` - Main container for inline loading component. Must be combined with a state modifier.
46
+
47
+ ### State Modifier Classes (on ga-inline-loading)
48
+
49
+ - `ga-inline-loading--active` - Active loading state with animated spinner icon
50
+ - `ga-inline-loading--completed` - Completed state with green CircleCheck icon
51
+ - `ga-inline-loading--error` - Error state with red OctagonAlert icon
52
+ - `ga-inline-loading--inactive` - Inactive state with disabled text color
53
+
54
+ ### Child Elements
55
+
56
+ - `ga-inline-loading__icon` - The inline loading icon
57
+ - Text content - Inline text next to the icon
58
+
59
+ ## Examples
60
+
61
+ ### Default
62
+
63
+ ### Small
64
+
65
+ ### Large
66
+
67
+ ### Without Label
68
+
69
+ ## Inline Loading Examples
70
+
71
+ ### Inline Loading Active
72
+
73
+ ### Inline Loading Completed
74
+
75
+ ### Inline Loading Error
76
+
77
+ ### Inline Loading Inactive
@@ -0,0 +1,96 @@
1
+ # Quantity Selector
2
+
3
+ ## Visual Structure
4
+
5
+ ```
6
+ ga-input ga-input--quantity-selector
7
+ ├── input
8
+ ├── ga-input__quantity-button (decrease)
9
+ ├── ga-input__quantity-separator
10
+ └── ga-input__quantity-button (increase)
11
+ ```
12
+
13
+ ## Elements Hierarchy
14
+
15
+ ### Core Block
16
+
17
+ - `ga-input ga-input--quantity-selector` - Quantity selector variant of the input component. Use `ga-input` for the outer input border/state styling.
18
+
19
+ ### Mandatory Elements
20
+
21
+ - `input` - The native HTML input element (use `type="number"` or `type="text"`)
22
+ - `ga-input__quantity-button` - Buttons for decreasing and increasing the value (use lucide `MinusIcon` and `PlusIcon`)
23
+ - `ga-input__quantity-separator` - A 1px vertical line separator between the buttons
24
+
25
+ ### Modifiers
26
+
27
+ - `ga-input--quantity-selector` - Styles the input as a quantity selector
28
+ - Use native `disabled` attributes on the input and buttons for disabled state
29
+
30
+ ## Examples
31
+
32
+ ### Default
33
+
34
+ ```html
35
+ <div class="ga-input ga-input--quantity-selector">
36
+ <input type="number" value="1" />
37
+ <button type="button" class="ga-input__quantity-button">
38
+ <!-- icon: minus, size=16 -->
39
+ </button>
40
+ <div class="ga-input__quantity-separator"></div>
41
+ <button type="button" class="ga-input__quantity-button">
42
+ <!-- icon: plus, size=16 -->
43
+ </button>
44
+ </div>
45
+ ```
46
+
47
+ ### Disabled Button
48
+
49
+ ```html
50
+ <div class="ga-input ga-input--quantity-selector">
51
+ <input type="number" value="0" />
52
+ <button type="button" class="ga-input__quantity-button" disabled="">
53
+ <!-- icon: minus, size=16 -->
54
+ </button>
55
+ <div class="ga-input__quantity-separator"></div>
56
+ <button type="button" class="ga-input__quantity-button">
57
+ <!-- icon: plus, size=16 -->
58
+ </button>
59
+ </div>
60
+ ```
61
+
62
+ ### Disabled Input
63
+
64
+ ```html
65
+ <div class="ga-input ga-input--quantity-selector">
66
+ <input type="number" placeholder="" disabled="" />
67
+ <button type="button" class="ga-input__quantity-button" disabled="">
68
+ <!-- icon: minus, size=16 -->
69
+ </button>
70
+ <div class="ga-input__quantity-separator"></div>
71
+ <button type="button" class="ga-input__quantity-button" disabled="">
72
+ <!-- icon: plus, size=16 -->
73
+ </button>
74
+ </div>
75
+ ```
76
+
77
+ ### Form Field Error
78
+
79
+ ```html
80
+ <div class="ga-form-field">
81
+ <div class="ga-input ga-input--invalid ga-input--quantity-selector">
82
+ <input type="number" value="0" />
83
+ <button type="button" class="ga-input__quantity-button">
84
+ <!-- icon: minus, size=16 -->
85
+ </button>
86
+ <div class="ga-input__quantity-separator"></div>
87
+ <button type="button" class="ga-input__quantity-button">
88
+ <!-- icon: plus, size=16 -->
89
+ </button>
90
+ </div>
91
+ <div class="ga-form-field__info">
92
+ <!-- icon: triangle-alert, size=16, class="ga-icon" -->
93
+ Hour entry cannot be zero.
94
+ </div>
95
+ </div>
96
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vsn-ux/gaia-styles",
3
- "version": "0.6.7",
3
+ "version": "0.6.8",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
21
21
  "./tailwindcss/components.css": "./src/styles/components.css",
22
22
  "./design-tokens.json": "./src/design-tokens/dtcg-tokens.json",
23
23
  "./font/*": "./src/font/*",
24
+ "./images/*": "./src/images/*",
24
25
  "./integrations/ag-grid": {
25
26
  "types": "./dist/integrations/ag-grid.d.mts",
26
27
  "default": "./dist/integrations/ag-grid.mjs"
@@ -68,6 +69,7 @@
68
69
  "dist/",
69
70
  "src/design-tokens/",
70
71
  "src/font/",
72
+ "src/images/",
71
73
  "src/styles/"
72
74
  ],
73
75
  "publishConfig": {
@@ -0,0 +1,4 @@
1
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M16 8C16 12.4183 12.4183 16 8 16C3.58172 16 0 12.4183 0 8C0 3.58172 3.58172 0 8 0C12.4183 0 16 3.58172 16 8ZM3.19967 8C3.19967 10.6511 5.34885 12.8003 8 12.8003C10.6511 12.8003 12.8003 10.6511 12.8003 8C12.8003 5.34885 10.6511 3.19967 8 3.19967C5.34885 3.19967 3.19967 5.34885 3.19967 8Z" fill="var(--ga-color-secondary, #FAE0CE)" />
3
+ <path d="M1.6 8C0.716345 8 -0.0160989 7.27665 0.159468 6.41061C0.386051 5.29292 0.8503 4.2303 1.52786 3.29772C2.52089 1.93094 3.92112 0.913611 5.52787 0.391547C7.13461 -0.130516 8.86539 -0.130516 10.4721 0.391549C11.5685 0.747766 12.5686 1.33456 13.4089 2.10561C14.06 2.70306 13.8926 3.71878 13.1777 4.23818C12.4628 4.75758 11.4711 4.56892 10.7464 4.06333C10.3609 3.79443 9.93576 3.58195 9.48328 3.43493C8.51923 3.12169 7.48077 3.12169 6.51672 3.43493C5.55267 3.74817 4.71253 4.35856 4.11672 5.17863C3.83707 5.56353 3.61799 5.98535 3.46421 6.42944C3.17509 7.26446 2.48366 8 1.6 8Z" fill="var(--ga-color-primary-70, #2A6480)" />
4
+ </svg>
@@ -0,0 +1,95 @@
1
+ .ga-file-uploader {
2
+ @apply flex flex-col gap-4;
3
+
4
+ .ga-file-uploader__heading {
5
+ @apply flex flex-1 flex-col gap-1;
6
+
7
+ .ga-file-uploader__heading-label {
8
+ @apply text-md align-middle font-medium;
9
+ }
10
+
11
+ .ga-file-uploader__heading-description {
12
+ @apply text-sm font-normal;
13
+ }
14
+ }
15
+
16
+ .ga-button {
17
+ @apply w-fit;
18
+ }
19
+
20
+ .ga-file-uploader__heading {
21
+ @apply text-(--ga-color-text-body);
22
+ }
23
+
24
+ &.ga-file-uploader--disabled .ga-file-uploader__heading {
25
+ @apply text-(--ga-color-text-disable-selected);
26
+ }
27
+
28
+ .ga-file-uploader__file-list {
29
+ @apply flex flex-1 flex-col gap-2;
30
+
31
+ .ga-file-uploader__file-item {
32
+ @apply text-md flex h-10 max-w-[58rem] min-w-[22rem] items-center justify-between rounded bg-(--ga-color-surface-disabled) px-2 py-1 font-normal text-(--ga-color-text-body);
33
+
34
+ .ga-file-uploader__file-action {
35
+ @apply flex h-4 w-4 cursor-pointer items-center justify-center rounded border-none bg-transparent p-0 text-(--ga-color-icon-action);
36
+
37
+ &:focus-visible {
38
+ @apply outline-2 outline-offset-2 outline-(--ga-color-border-focus);
39
+ }
40
+ }
41
+
42
+ .ga-file-uploader__file-icon {
43
+ @apply h-4 w-4;
44
+ }
45
+
46
+ &.ga-file-uploader__file-item--success {
47
+ .ga-file-uploader__file-icon {
48
+ @apply text-(--ga-color-icon-success);
49
+ }
50
+ }
51
+
52
+ &.ga-file-uploader__file-item--error {
53
+ @apply h-auto flex-col items-start gap-2 border border-(--ga-color-border-error) bg-(--ga-color-surface-error) outline outline-(--ga-color-border-error);
54
+
55
+ .ga-file-uploader__error-file {
56
+ @apply flex w-full items-center justify-between leading-6;
57
+ }
58
+
59
+ .ga-file-uploader__error-callout {
60
+ @apply flex flex-row items-center gap-1 align-middle text-xs font-normal;
61
+
62
+ .ga-file-uploader__error-callout-icon {
63
+ @apply h-4 w-4 text-(--ga-color-icon-error);
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ .ga-file-uploader__input {
71
+ @apply sr-only;
72
+ }
73
+
74
+ .ga-file-uploader__dropzone {
75
+ @apply text-md flex min-h-[6.25rem] flex-1 items-center justify-center rounded border border-dashed border-(--ga-color-border-action) p-8 text-center font-normal text-(--ga-color-text-action);
76
+
77
+ &:hover {
78
+ @apply border-(--ga-color-border-action-hover) bg-(--ga-color-surface-action-hover-2) text-(--ga-color-text-action-hover);
79
+ }
80
+
81
+ &:focus-visible,
82
+ &:focus-within {
83
+ @apply border-none outline-2 outline-(--ga-color-border-focus) outline-solid;
84
+ }
85
+
86
+ &.ga-file-uploader__dropzone--drag-hover {
87
+ @apply border-none bg-(--ga-color-surface-page) text-(--ga-color-text-action-hover) outline-2 outline-(--ga-color-border-focus) outline-solid;
88
+ }
89
+ }
90
+
91
+ .ga-file-uploader__dropzone[aria-disabled='true'],
92
+ &.ga-file-uploader--disabled .ga-file-uploader__dropzone {
93
+ @apply cursor-not-allowed border-(--ga-color-border-disabled) bg-(--ga-color-surface-primary) text-(--ga-color-text-disabled);
94
+ }
95
+ }
@@ -0,0 +1,108 @@
1
+ .ga-loader {
2
+ @apply flex flex-col items-center justify-center gap-2;
3
+
4
+ &.ga-loader--small {
5
+ @apply text-xs;
6
+
7
+ .ga-loader__icon {
8
+ @apply h-4 w-4;
9
+ }
10
+ }
11
+
12
+ &.ga-loader--medium {
13
+ @apply text-sm;
14
+
15
+ .ga-loader__icon {
16
+ @apply h-8 w-8;
17
+ }
18
+ }
19
+
20
+ &.ga-loader--large {
21
+ @apply text-md;
22
+
23
+ .ga-loader__icon {
24
+ @apply h-16 w-16;
25
+ }
26
+ }
27
+
28
+ .ga-loader__icon--animated {
29
+ @apply animate-[ga-loader-animation_1100ms_linear_infinite];
30
+ }
31
+
32
+ .ga-loader__icon--reduced-motion {
33
+ @apply hidden text-(--ga-color-icon-primary);
34
+ }
35
+
36
+ @media (prefers-reduced-motion: reduce) {
37
+ .ga-loader__icon--animated {
38
+ @apply hidden;
39
+ }
40
+
41
+ .ga-loader__icon--reduced-motion {
42
+ @apply block;
43
+ }
44
+ }
45
+
46
+ .ga-loader__label {
47
+ @apply text-(--ga-color-text-body);
48
+
49
+ &:empty {
50
+ @apply hidden;
51
+ }
52
+ }
53
+ }
54
+
55
+ .ga-inline-loading {
56
+ @apply flex flex-row items-center gap-1 text-sm text-(--ga-color-text-body);
57
+
58
+ &.ga-inline-loading--active {
59
+ .ga-inline-loading__icon {
60
+ @apply h-4 w-4 animate-[ga-loader-animation_1100ms_linear_infinite];
61
+ }
62
+ }
63
+
64
+ &.ga-inline-loading--completed {
65
+ .ga-inline-loading__icon {
66
+ @apply text-(--ga-color-icon-success);
67
+ }
68
+ }
69
+
70
+ &.ga-inline-loading--error {
71
+ .ga-inline-loading__icon {
72
+ @apply text-(--ga-color-icon-error);
73
+ }
74
+ }
75
+
76
+ &.ga-inline-loading--inactive {
77
+ @apply text-(--ga-color-text-disable-selected);
78
+ }
79
+
80
+ .ga-inline-loading__icon {
81
+ @apply h-4 w-4;
82
+ }
83
+ }
84
+
85
+ @keyframes ga-loader-animation {
86
+ 0% {
87
+ transform: rotate(0deg);
88
+ }
89
+
90
+ 31.82% {
91
+ /* 350ms / 1100ms */
92
+ transform: rotate(90deg);
93
+ }
94
+
95
+ 63.64% {
96
+ /* (350ms + 350ms) / 1100ms */
97
+ transform: rotate(180deg);
98
+ }
99
+
100
+ 81.82% {
101
+ /* (350ms + 350ms + 200ms) / 1100ms */
102
+ transform: rotate(270deg);
103
+ }
104
+
105
+ 100% {
106
+ transform: rotate(360deg);
107
+ }
108
+ }
@@ -0,0 +1,45 @@
1
+ .ga-input--quantity-selector {
2
+ @apply w-40 px-2;
3
+
4
+ &:has(input:disabled):has(input:not(:placeholder-shown)) {
5
+ .ga-input__quantity-separator {
6
+ @apply bg-(--ga-color-text-on-action);
7
+ }
8
+
9
+ .ga-input__quantity-button {
10
+ @apply text-(--ga-color-text-on-action);
11
+ }
12
+ }
13
+
14
+ input {
15
+ @apply min-w-0 flex-1 bg-transparent px-2 leading-6 outline-none;
16
+
17
+ appearance: textfield;
18
+
19
+ &::-webkit-outer-spin-button,
20
+ &::-webkit-inner-spin-button {
21
+ -webkit-appearance: none;
22
+ margin: 0;
23
+ }
24
+ }
25
+
26
+ .ga-input__quantity-separator {
27
+ @apply h-6 w-px bg-(--ga-color-border-disabled);
28
+ }
29
+
30
+ .ga-input__quantity-button {
31
+ @apply flex w-6 shrink-0 cursor-pointer items-center justify-center bg-transparent p-1;
32
+
33
+ &:hover:not(:disabled) {
34
+ @apply rounded bg-(--ga-color-surface-action-hover-2) outline-1 outline-(--ga-color-border-action-hover);
35
+ }
36
+
37
+ &:focus-visible {
38
+ @apply rounded outline-2 outline-offset-2 outline-(--ga-color-border-focus);
39
+ }
40
+
41
+ &:disabled {
42
+ @apply cursor-not-allowed bg-transparent text-(--ga-color-text-disabled);
43
+ }
44
+ }
45
+ }
@@ -8,8 +8,10 @@
8
8
  @import './components/container.css';
9
9
  @import './components/datepicker.css';
10
10
  @import './components/dropdown.css';
11
+ @import './components/file-uploader.css';
11
12
  @import './components/form-field.css';
12
13
  @import './components/input.css';
14
+ @import './components/loader.css';
13
15
  @import './components/notification.css';
14
16
  @import './components/menu.css';
15
17
  @import './components/modal.css';
@@ -26,5 +28,6 @@
26
28
  @import './components/text-size.css';
27
29
  @import './components/tooltip.css';
28
30
  @import './components/link.css';
31
+ @import './components/quantity-selector.css';
29
32
  @import './components/quick-filter-button.css';
30
33
  @import './components/side-navigation.css';