@mantis-core/styles 0.1.2 → 0.2.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.
package/README.md CHANGED
@@ -1,67 +1,60 @@
1
1
  # @mantis-core/styles
2
2
 
3
- Shared SCSS tokens and style overrides for Mantis Core components.
3
+ Shared raw SCSS modules and style contracts for Mantis Core packages.
4
+
5
+ ## Purpose
6
+
7
+ `@mantis-core/styles` ships reusable SCSS partials that style PrimeReact controls, `react-select`, CKEditor content, and Mantis-specific `mantis-core-*` class contracts.
4
8
 
5
9
  ## Scope
6
10
 
7
- - Shared visual tokens.
8
- - PrimeReact-oriented overrides.
9
- - Namespace contract: `mantis-core-*`.
11
+ - Shared visual contracts used by `@mantis-core/ui`
12
+ - PrimeReact-oriented overrides
13
+ - SCSS partials that assume shared design tokens such as `--primary`, `--border`, and `--card`
10
14
 
11
- ## Out Of Scope
15
+ ## Out of Scope
12
16
 
13
- - App/domain-specific styles.
14
- - Client brand names in class prefixes.
17
+ - App-specific branding rules outside token values
18
+ - Runtime style injection
19
+ - React components
15
20
 
16
- ## Exports
21
+ ## Export Model
17
22
 
18
23
  - `@mantis-core/styles` -> `scss/index.scss`
19
- - `@mantis-core/styles/scss/*` -> direct SCSS partials
20
-
21
- ## File Structure
22
-
23
- ```text
24
- scss/
25
- index.scss
26
- buttons.scss
27
- ckeditor.scss
28
- date-picker.scss
29
- gallery.scss
30
- inputs.scss
31
- paginator.scss
32
- rich-text-preview.scss
33
- select.scss
34
- select-button.scss
35
- switch.scss
36
- table.scss
37
- ```
24
+ - `@mantis-core/styles/scss/*` -> direct raw SCSS partials
25
+
26
+ The package ships raw SCSS. Consumers are expected to import the partials they need from their app stylesheet pipeline.
38
27
 
39
28
  ## Usage
40
29
 
30
+ Import everything:
31
+
41
32
  ```scss
42
- @use "@mantis-core/styles/scss/index.scss";
33
+ @use "@mantis-core/styles";
43
34
  ```
44
35
 
45
- Or import only what you need:
36
+ Import selectively:
46
37
 
47
38
  ```scss
39
+ @use "@mantis-core/styles/scss/buttons.scss";
40
+ @use "@mantis-core/styles/scss/inputs.scss";
48
41
  @use "@mantis-core/styles/scss/table.scss";
49
- @use "@mantis-core/styles/scss/paginator.scss";
50
42
  ```
51
43
 
52
- ## Styling Contract
44
+ ## Documentation Index
53
45
 
54
- When consuming components from `@mantis-core/ui`, include the style modules that define:
46
+ - [docs/README.md](./docs/README.md): package documentation index
47
+ - [STYLES.md](./STYLES.md): lightweight partial index
48
+ - [STYLE_CONTRACTS.md](./STYLE_CONTRACTS.md): lightweight style-contract pointer
55
49
 
56
- - `mantis-core-table*`
57
- - `mantis-core-table-toolbar*`
58
- - `mantis-core-table-filters*`
59
- - `mantis-core-paginator`
50
+ ## Important Notes
60
51
 
61
- ## Build
52
+ 1. This package does not define the global tokens themselves. It expects them to exist in the consuming app.
53
+ 2. Some partials style third-party markup directly, such as PrimeReact selectors or `react-select` class names.
54
+ 3. Some partials expose first-class `mantis-core-*` contracts that are intended to be stable across apps.
62
55
 
63
- `@mantis-core/styles` ships raw SCSS (no TS output):
56
+ ## Local Validation
64
57
 
65
58
  ```bash
66
59
  pnpm --filter @mantis-core/styles build
67
- ```
60
+ ```
package/STYLES.md ADDED
@@ -0,0 +1,11 @@
1
+ # @mantis-core/styles Partial Index
2
+
3
+ The detailed SCSS documentation now lives in focused files under [`docs/`](./docs/README.md).
4
+
5
+ ## Start Here
6
+
7
+ - [Documentation index](./docs/README.md)
8
+ - [Style contracts](./docs/contracts/style-contracts.md)
9
+ - [Table styles](./docs/styles/table.md)
10
+ - [Button styles](./docs/styles/buttons.md)
11
+ - [Select styles](./docs/styles/select.md)
@@ -0,0 +1,6 @@
1
+ # @mantis-core/styles Style Contracts
2
+
3
+ The detailed style-contract reference now lives in:
4
+
5
+ - [docs/contracts/style-contracts.md](./docs/contracts/style-contracts.md)
6
+ - [docs/README.md](./docs/README.md)
package/docs/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # @mantis-core/styles Docs
2
+
3
+ This folder contains focused documentation for each SCSS partial and the shared style contracts.
4
+
5
+ ## Contracts
6
+
7
+ - [Style contracts](./contracts/style-contracts.md)
8
+
9
+ ## Partials
10
+
11
+ - [index.scss](./styles/index.md)
12
+ - [buttons.scss](./styles/buttons.md)
13
+ - [ckeditor.scss](./styles/ckeditor.md)
14
+ - [confirm-dialog.scss](./styles/confirm-dialog.md)
15
+ - [data-state.scss](./styles/data-state.md)
16
+ - [date-picker.scss](./styles/date-picker.md)
17
+ - [file-dropzone.scss](./styles/file-dropzone.md)
18
+ - [form-actions.scss](./styles/form-actions.md)
19
+ - [gallery.scss](./styles/gallery.md)
20
+ - [inputs.scss](./styles/inputs.md)
21
+ - [paginator.scss](./styles/paginator.md)
22
+ - [rich-text-preview.scss](./styles/rich-text-preview.md)
23
+ - [select.scss](./styles/select.md)
24
+ - [select-button.scss](./styles/select-button.md)
25
+ - [status-badge.scss](./styles/status-badge.md)
26
+ - [switch.scss](./styles/switch.md)
27
+ - [table.scss](./styles/table.md)
@@ -0,0 +1,35 @@
1
+ # Style Contracts
2
+
3
+ These are the canonical class families and package mappings that should remain stable.
4
+
5
+ ## Canonical `mantis-core-*` families
6
+
7
+ - `mantis-core-table*`
8
+ - `mantis-core-table-toolbar*`
9
+ - `mantis-core-table-filters*`
10
+ - `mantis-core-status-badge*`
11
+ - `mantis-core-data-state*`
12
+ - `mantis-core-confirm-dialog*`
13
+ - `mantis-core-form-actions*`
14
+ - `mantis-core-file-dropzone*`
15
+ - `mantis-core-paginator`
16
+
17
+ ## UI mappings
18
+
19
+ - `PaginatedTable`, `TableToolbar`, `TableFilterField` -> `table.scss`
20
+ - `StatusBadge` -> `status-badge.scss`
21
+ - `DataState` -> `data-state.scss`
22
+ - `ConfirmDialog` -> `confirm-dialog.scss`
23
+ - `FormActionsBar` -> `form-actions.scss`
24
+ - `FileDropzone` -> `file-dropzone.scss`
25
+ - `Button` -> `buttons.scss`
26
+ - `Select`, `AsyncSelect` -> `select.scss`
27
+ - `ToggleInlineButton` -> `select-button.scss`
28
+ - `Switch` -> `switch.scss`
29
+ - `CKEditorInput` -> `ckeditor.scss`
30
+ - `RichTextPreview` -> `rich-text-preview.scss`
31
+
32
+ ## Caveats
33
+
34
+ - `Pagination` from `@mantis-core/ui` is custom and is not styled by `paginator.scss`.
35
+ - `gallery.scss` is currently empty and should not be treated as an implemented gallery contract.
@@ -0,0 +1,10 @@
1
+ # buttons.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/buttons.scss";`
4
+ - Targets: PrimeReact button classes, `Button`, `MenuButton`
5
+ - Main selectors: `.p-button-*`, `.p-button-outlined`, `.p-button-text`, `.p-button-link`, `.p-button-raised`, `.p-button-premium`
6
+ - Token assumptions: `--primary`, `--secondary`, `--accent`, `--success`, `--warning`, `--error`, `--info`, `--bluegray-500`
7
+
8
+ ## Notes
9
+
10
+ - The token loop defines `error`, not a dedicated `danger` alias.
@@ -0,0 +1,6 @@
1
+ # ckeditor.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/ckeditor.scss";`
4
+ - Targets: `CKEditorInput`
5
+ - Main selectors: `.ckeditor-wrapper`, `.ckeditor-invalid`, `.ckeditor-disabled`, `.ckeditor-meta`, `.ck-*`, `.ck-content`
6
+ - Token assumptions: `--border`, `--input`, `--card`, `--foreground`, `--muted-foreground`, `--primary`, `--error`, `--font-sans`, `--font-display`
@@ -0,0 +1,6 @@
1
+ # confirm-dialog.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/confirm-dialog.scss";`
4
+ - Targets: `ConfirmDialog`
5
+ - Main selectors: `.mantis-core-confirm-dialog*`, `.p-dialog-content`, `.p-dialog-header`
6
+ - Token assumptions: `--card`, `--foreground`, `--accent`, `--muted-foreground`
@@ -0,0 +1,6 @@
1
+ # data-state.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/data-state.scss";`
4
+ - Targets: `DataState`
5
+ - Main selectors: `.mantis-core-data-state*`, `.mantis-core-data-state__icon--spin`
6
+ - Token assumptions: `--border`, `--foreground`, `--card`, `--primary`, `--muted`, `--muted-foreground`, `--error`
@@ -0,0 +1,7 @@
1
+ # date-picker.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/date-picker.scss";`
4
+ - Targets: `DateInput`
5
+ - Main selectors: `.p-calendar`, `.p-calendar-w-btn`, `.p-datepicker-trigger`, `.p-invalid`, `.p-disabled`, `.p-button`
6
+ - Token assumptions: same shared input tokens plus `--primary`, `--error`
7
+ - Notes: complements `inputs.scss`; it does not replace it
@@ -0,0 +1,6 @@
1
+ # file-dropzone.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/file-dropzone.scss";`
4
+ - Targets: `FileDropzone`
5
+ - Main selectors: `.mantis-core-file-dropzone*`
6
+ - Token assumptions: `--border`, `--foreground`, `--muted`, `--muted-foreground`, `--primary`, `--accent`, `--error`
@@ -0,0 +1,6 @@
1
+ # form-actions.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/form-actions.scss";`
4
+ - Targets: `FormActionsBar`
5
+ - Main selectors: `.mantis-core-form-actions*`
6
+ - Token assumptions: `--card`
@@ -0,0 +1,10 @@
1
+ # gallery.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/gallery.scss";`
4
+ - Targets: none currently
5
+ - Main selectors: none
6
+
7
+ ## Notes
8
+
9
+ - This file is currently empty.
10
+ - Treat it as a reserved placeholder, not as an implemented gallery contract.
@@ -0,0 +1,6 @@
1
+ # index.scss
2
+
3
+ - Import: `@use "@mantis-core/styles";`
4
+ - Purpose: aggregate all shipped SCSS partials
5
+ - Primary consumers: apps that want the full style bundle
6
+ - Notes: no selectors of its own; it only `@use`s the other partials
@@ -0,0 +1,6 @@
1
+ # inputs.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/inputs.scss";`
4
+ - Targets: `TextInput`, `TextArea`, `NumberInput`, `DropDown`, `MultiSelect`, `DateInput`
5
+ - Main selectors: `.p-inputtext`, `.p-dropdown`, `.p-multiselect`, `.p-inputnumber`, `.p-calendar`, `.p-focus`, `.p-invalid`, `.p-disabled`
6
+ - Token assumptions: `--border`, `--primary`, `--error`
@@ -0,0 +1,10 @@
1
+ # paginator.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/paginator.scss";`
4
+ - Targets: PrimeReact `Paginator` instances carrying `mantis-core-paginator`
5
+ - Main selectors: `.mantis-core-paginator.p-paginator`, `.p-paginator-element`, `.p-paginator-page.p-highlight`, `.p-disabled`
6
+ - Token assumptions: `--card`, `--background`, `--border`, `--foreground`, `--muted`, `--muted-foreground`, `--primary`
7
+
8
+ ## Notes
9
+
10
+ - This partial does not style the custom `Pagination` component exported by `@mantis-core/ui`.
@@ -0,0 +1,6 @@
1
+ # rich-text-preview.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/rich-text-preview.scss";`
4
+ - Targets: `RichTextPreview`
5
+ - Main selectors: `.rich-text-preview` and its nested heading, list, blockquote, table, code, and size classes
6
+ - Token assumptions: `--foreground`, `--primary`, `--accent`, `--border`, `--muted`, `--font-sans`, `--font-display`
@@ -0,0 +1,6 @@
1
+ # select-button.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/select-button.scss";`
4
+ - Targets: `ToggleInlineButton`
5
+ - Main selectors: `.p-selectbutton-*`, `.p-highlight`, `.p-disabled`, `.p-focus`
6
+ - Token assumptions: same semantic button tokens used by `buttons.scss`
@@ -0,0 +1,10 @@
1
+ # select.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/select.scss";`
4
+ - Targets: `Select`, `AsyncSelect`
5
+ - Main selectors: `.select-input`, `.select-variant-*`, `.select-invalid`, `.react-select__*`
6
+ - Token assumptions: `--primary`, `--secondary`, `--accent`, `--success`, `--warning`, `--error`, `--info`, `--bluegray-500`, `--border`, `--card`, `--foreground`, `--muted-foreground`
7
+
8
+ ## Notes
9
+
10
+ - This partial depends on `classNamePrefix="react-select"` remaining unchanged.
@@ -0,0 +1,6 @@
1
+ # status-badge.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/status-badge.scss";`
4
+ - Targets: `StatusBadge`
5
+ - Main selectors: `.mantis-core-status-badge*`
6
+ - Token assumptions: `--success`, `--muted`, `--border`, `--foreground`, `--warning`, `--info`, `--error`
@@ -0,0 +1,6 @@
1
+ # switch.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/switch.scss";`
4
+ - Targets: `Switch`
5
+ - Main selectors: `.bootstrap-switch-*`
6
+ - Token assumptions: `--border`, `--ring`, `--primary`, `--secondary`, `--success`, `--error`, `--warning`, `--info`, `--foreground`, `--background`, `--muted`, `--muted-foreground`
@@ -0,0 +1,11 @@
1
+ # table.scss
2
+
3
+ - Import: `@use "@mantis-core/styles/scss/table.scss";`
4
+ - Targets: `PaginatedTable`, `TableToolbar`, `TableFilterField`
5
+ - Main selectors:
6
+ - `.mantis-core-table*`
7
+ - `.mantis-core-table-toolbar*`
8
+ - `.mantis-core-table-filters*`
9
+ - `.mantis-core-table__badge*`
10
+ - PrimeReact internals such as `.p-datatable-*`, `.p-column-header-content`, `.p-sortable-column`, `.p-paginator`
11
+ - Token assumptions: `--card`, `--primary`, `--accent`, `--border`, `--foreground`, `--background`, `--muted`, `--muted-foreground`, `--ring`, `--success`, `--warning`, `--info`, `--error`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mantis-core/styles",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "description": "Shared SCSS tokens and Mantis Core style overrides.",
6
6
  "type": "module",
@@ -18,7 +18,10 @@
18
18
  },
19
19
  "files": [
20
20
  "scss",
21
- "README.md"
21
+ "docs",
22
+ "README.md",
23
+ "STYLES.md",
24
+ "STYLE_CONTRACTS.md"
22
25
  ],
23
26
  "publishConfig": {
24
27
  "access": "public"
@@ -41,7 +44,7 @@
41
44
  ],
42
45
  "scripts": {
43
46
  "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
44
- "build": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\" && echo \"@mantis-core/styles uses raw scss files\"",
47
+ "build": "echo \"@mantis-core/styles uses raw scss files\"",
45
48
  "typecheck": "echo \"@mantis-core/styles has no ts sources\""
46
49
  }
47
50
  }
@@ -0,0 +1,57 @@
1
+ .mantis-core-confirm-dialog {
2
+ .p-dialog-content {
3
+ background: var(--card);
4
+ color: var(--foreground);
5
+ padding: 1.1rem 1.2rem 1.2rem;
6
+ }
7
+
8
+ .p-dialog-header {
9
+ display: none;
10
+ }
11
+ }
12
+
13
+ .mantis-core-confirm-dialog__body {
14
+ display: grid;
15
+ justify-items: center;
16
+ text-align: center;
17
+ gap: 0.7rem;
18
+ }
19
+
20
+ .mantis-core-confirm-dialog__icon {
21
+ width: 2.35rem;
22
+ height: 2.35rem;
23
+ border-radius: 999px;
24
+ display: inline-flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ background: color-mix(in oklch, var(--accent), white 88%);
28
+ color: color-mix(in oklch, var(--accent), black 18%);
29
+ }
30
+
31
+ .mantis-core-confirm-dialog__title {
32
+ margin: 0;
33
+ color: color-mix(in oklch, var(--foreground), black 12%);
34
+ font-size: 1.05rem;
35
+ font-weight: 700;
36
+ line-height: 1.3;
37
+ }
38
+
39
+ .mantis-core-confirm-dialog__message {
40
+ color: var(--muted-foreground);
41
+ font-size: 0.9rem;
42
+ line-height: 1.45;
43
+ }
44
+
45
+ .mantis-core-confirm-dialog__actions {
46
+ margin-top: 1rem;
47
+ display: flex;
48
+ justify-content: flex-end;
49
+ gap: 0.5rem;
50
+ }
51
+
52
+ @media (max-width: 640px) {
53
+ .mantis-core-confirm-dialog__actions {
54
+ display: grid;
55
+ grid-template-columns: 1fr;
56
+ }
57
+ }
@@ -0,0 +1,64 @@
1
+ .mantis-core-data-state {
2
+ border: 1px solid color-mix(in oklch, var(--border), var(--foreground) 8%);
3
+ border-radius: 0.9rem;
4
+ background: var(--card);
5
+ padding: 1.5rem 1.25rem;
6
+ text-align: center;
7
+ display: grid;
8
+ justify-items: center;
9
+ gap: 0.65rem;
10
+ }
11
+
12
+ .mantis-core-data-state__icon {
13
+ width: 2.25rem;
14
+ height: 2.25rem;
15
+ border-radius: 999px;
16
+ display: inline-flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ }
20
+
21
+ .mantis-core-data-state--loading .mantis-core-data-state__icon {
22
+ background: color-mix(in oklch, var(--primary), white 90%);
23
+ color: color-mix(in oklch, var(--primary), black 12%);
24
+ }
25
+
26
+ .mantis-core-data-state--empty .mantis-core-data-state__icon {
27
+ background: color-mix(in oklch, var(--muted), white 45%);
28
+ color: color-mix(in oklch, var(--muted-foreground), black 5%);
29
+ }
30
+
31
+ .mantis-core-data-state--error .mantis-core-data-state__icon {
32
+ background: color-mix(in oklch, var(--error), white 90%);
33
+ color: color-mix(in oklch, var(--error), black 12%);
34
+ }
35
+
36
+ .mantis-core-data-state__icon--spin {
37
+ animation: mantis-core-spin 1s linear infinite;
38
+ }
39
+
40
+ .mantis-core-data-state__title {
41
+ margin: 0;
42
+ color: color-mix(in oklch, var(--foreground), black 10%);
43
+ font-size: 1rem;
44
+ font-weight: 700;
45
+ line-height: 1.2;
46
+ }
47
+
48
+ .mantis-core-data-state__description {
49
+ margin: 0;
50
+ color: var(--muted-foreground);
51
+ font-size: 0.875rem;
52
+ max-width: 40ch;
53
+ line-height: 1.45;
54
+ }
55
+
56
+ .mantis-core-data-state__action {
57
+ margin-top: 0.45rem;
58
+ }
59
+
60
+ @keyframes mantis-core-spin {
61
+ to {
62
+ transform: rotate(360deg);
63
+ }
64
+ }
@@ -0,0 +1,145 @@
1
+ .mantis-core-file-dropzone {
2
+ display: grid;
3
+ gap: 0.7rem;
4
+ }
5
+
6
+ .mantis-core-file-dropzone__label {
7
+ margin: 0;
8
+ font-size: 0.78rem;
9
+ font-weight: 600;
10
+ color: color-mix(in oklch, var(--foreground), black 10%);
11
+ }
12
+
13
+ .mantis-core-file-dropzone__zone {
14
+ border: 2px dashed color-mix(in oklch, var(--primary), white 52%);
15
+ border-radius: 0.8rem;
16
+ background: color-mix(in oklch, var(--primary), white 96%);
17
+ display: grid;
18
+ justify-items: center;
19
+ text-align: center;
20
+ gap: 0.45rem;
21
+ padding: 1.1rem 1rem;
22
+ transition:
23
+ border-color 0.18s ease,
24
+ background-color 0.18s ease;
25
+ }
26
+
27
+ .mantis-core-file-dropzone__zone:hover {
28
+ border-color: color-mix(in oklch, var(--primary), black 10%);
29
+ }
30
+
31
+ .mantis-core-file-dropzone__zone--drag {
32
+ border-color: var(--primary);
33
+ background: color-mix(in oklch, var(--primary), white 90%);
34
+ }
35
+
36
+ .mantis-core-file-dropzone__zone--disabled {
37
+ cursor: not-allowed;
38
+ opacity: 0.7;
39
+ }
40
+
41
+ .mantis-core-file-dropzone__icon {
42
+ width: 2.2rem;
43
+ height: 2.2rem;
44
+ border-radius: 999px;
45
+ display: inline-flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ background: color-mix(in oklch, var(--primary), white 82%);
49
+ color: color-mix(in oklch, var(--primary), black 8%);
50
+ }
51
+
52
+ .mantis-core-file-dropzone__title {
53
+ margin: 0;
54
+ color: color-mix(in oklch, var(--foreground), black 12%);
55
+ font-size: 0.88rem;
56
+ font-weight: 700;
57
+ }
58
+
59
+ .mantis-core-file-dropzone__hint {
60
+ margin: 0;
61
+ color: var(--muted-foreground);
62
+ font-size: 0.75rem;
63
+ }
64
+
65
+ .mantis-core-file-dropzone__list {
66
+ list-style: none;
67
+ margin: 0;
68
+ padding: 0;
69
+ display: grid;
70
+ gap: 0.45rem;
71
+ }
72
+
73
+ .mantis-core-file-dropzone__item {
74
+ border: 1px solid color-mix(in oklch, var(--border), var(--foreground) 8%);
75
+ border-radius: 0.65rem;
76
+ background: var(--card);
77
+ padding: 0.45rem 0.55rem;
78
+ display: flex;
79
+ align-items: center;
80
+ justify-content: space-between;
81
+ gap: 0.6rem;
82
+ }
83
+
84
+ .mantis-core-file-dropzone__item-copy {
85
+ min-width: 0;
86
+ display: flex;
87
+ align-items: center;
88
+ gap: 0.45rem;
89
+ color: var(--muted-foreground);
90
+ }
91
+
92
+ .mantis-core-file-dropzone__item-name {
93
+ color: color-mix(in oklch, var(--foreground), black 12%);
94
+ font-size: 0.82rem;
95
+ font-weight: 600;
96
+ overflow: hidden;
97
+ text-overflow: ellipsis;
98
+ white-space: nowrap;
99
+ }
100
+
101
+ .mantis-core-file-dropzone__item-size {
102
+ font-size: 0.72rem;
103
+ }
104
+
105
+ .mantis-core-file-dropzone__remove {
106
+ border: 0;
107
+ border-radius: 0.45rem;
108
+ background: color-mix(in oklch, var(--error), white 90%);
109
+ color: color-mix(in oklch, var(--error), black 10%);
110
+ width: 1.55rem;
111
+ height: 1.55rem;
112
+ display: inline-flex;
113
+ align-items: center;
114
+ justify-content: center;
115
+ cursor: pointer;
116
+ }
117
+
118
+ .mantis-core-file-dropzone__remove:hover {
119
+ background: color-mix(in oklch, var(--error), white 80%);
120
+ }
121
+
122
+ .mantis-core-file-dropzone__remove:disabled {
123
+ opacity: 0.6;
124
+ cursor: not-allowed;
125
+ }
126
+
127
+ .mantis-core-file-dropzone__error-list {
128
+ list-style: none;
129
+ margin: 0;
130
+ padding: 0;
131
+ display: grid;
132
+ gap: 0.35rem;
133
+ }
134
+
135
+ .mantis-core-file-dropzone__error-item {
136
+ font-size: 0.74rem;
137
+ color: color-mix(in oklch, var(--error), black 15%);
138
+ display: flex;
139
+ align-items: center;
140
+ gap: 0.35rem;
141
+ }
142
+
143
+ .mantis-core-file-dropzone__error-item svg {
144
+ flex-shrink: 0;
145
+ }
@@ -0,0 +1,56 @@
1
+ .mantis-core-form-actions {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 0.75rem;
5
+ width: 100%;
6
+ flex-wrap: wrap;
7
+ }
8
+
9
+ .mantis-core-form-actions--start {
10
+ justify-content: flex-start;
11
+ }
12
+
13
+ .mantis-core-form-actions--end {
14
+ justify-content: flex-end;
15
+ }
16
+
17
+ .mantis-core-form-actions--between {
18
+ justify-content: space-between;
19
+ }
20
+
21
+ .mantis-core-form-actions--sticky {
22
+ position: sticky;
23
+ bottom: 0;
24
+ z-index: 10;
25
+ padding: 0.75rem 0;
26
+ background: linear-gradient(
27
+ to top,
28
+ color-mix(in oklch, var(--card), white 10%) 70%,
29
+ color-mix(in oklch, var(--card), transparent 100%)
30
+ );
31
+ }
32
+
33
+ .mantis-core-form-actions__left {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 0.5rem;
37
+ }
38
+
39
+ .mantis-core-form-actions__right {
40
+ display: flex;
41
+ align-items: center;
42
+ gap: 0.5rem;
43
+ margin-left: auto;
44
+ flex-wrap: wrap;
45
+ }
46
+
47
+ @media (max-width: 640px) {
48
+ .mantis-core-form-actions,
49
+ .mantis-core-form-actions__right {
50
+ width: 100%;
51
+ }
52
+
53
+ .mantis-core-form-actions__right > * {
54
+ width: 100%;
55
+ }
56
+ }
package/scss/index.scss CHANGED
@@ -9,3 +9,8 @@
9
9
  @use "./ckeditor.scss";
10
10
  @use "./rich-text-preview.scss";
11
11
  @use "./switch.scss";
12
+ @use "./status-badge.scss";
13
+ @use "./data-state.scss";
14
+ @use "./confirm-dialog.scss";
15
+ @use "./form-actions.scss";
16
+ @use "./file-dropzone.scss";
@@ -0,0 +1,58 @@
1
+ .mantis-core-status-badge {
2
+ border: 1px solid transparent;
3
+ border-radius: 999px;
4
+ display: inline-flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ font-weight: 700;
8
+ line-height: 1;
9
+ white-space: nowrap;
10
+ }
11
+
12
+ .mantis-core-status-badge--sm {
13
+ font-size: 0.7rem;
14
+ min-height: 1.35rem;
15
+ min-width: 4.9rem;
16
+ padding: 0.2rem 0.5rem;
17
+ }
18
+
19
+ .mantis-core-status-badge--md {
20
+ font-size: 0.75rem;
21
+ min-height: 1.55rem;
22
+ min-width: 5.6rem;
23
+ padding: 0.24rem 0.6rem;
24
+ }
25
+
26
+ .mantis-core-status-badge--block {
27
+ width: 100%;
28
+ }
29
+
30
+ .mantis-core-status-badge--success {
31
+ background-color: color-mix(in oklch, var(--success), white 86%);
32
+ border-color: color-mix(in oklch, var(--success), white 62%);
33
+ color: color-mix(in oklch, var(--success), black 20%);
34
+ }
35
+
36
+ .mantis-core-status-badge--muted {
37
+ background-color: color-mix(in oklch, var(--muted), white 35%);
38
+ border-color: color-mix(in oklch, var(--border), var(--foreground) 6%);
39
+ color: color-mix(in oklch, var(--foreground), white 28%);
40
+ }
41
+
42
+ .mantis-core-status-badge--warning {
43
+ background-color: color-mix(in oklch, var(--warning), white 84%);
44
+ border-color: color-mix(in oklch, var(--warning), white 60%);
45
+ color: color-mix(in oklch, var(--warning), black 24%);
46
+ }
47
+
48
+ .mantis-core-status-badge--info {
49
+ background-color: color-mix(in oklch, var(--info), white 84%);
50
+ border-color: color-mix(in oklch, var(--info), white 60%);
51
+ color: color-mix(in oklch, var(--info), black 24%);
52
+ }
53
+
54
+ .mantis-core-status-badge--danger {
55
+ background-color: color-mix(in oklch, var(--error), white 84%);
56
+ border-color: color-mix(in oklch, var(--error), white 60%);
57
+ color: color-mix(in oklch, var(--error), black 24%);
58
+ }
@@ -0,0 +1,122 @@
1
+ /*
2
+ * ============================================================
3
+ * MANTIS CORE — DESIGN TOKENS TEMPLATE
4
+ * ============================================================
5
+ *
6
+ * THIS IS A TEMPLATE — do NOT @use/@import this file directly
7
+ * into scss/index.scss or any Core partial.
8
+ *
9
+ * HOW TO USE:
10
+ * 1. Copy the :root and .dark blocks below into your app's
11
+ * global stylesheet (e.g. src/app/globals.scss).
12
+ * 2. Replace the OKLCH values with your brand palette.
13
+ * 3. All @mantis-core/styles components consume these tokens
14
+ * via var(--token-name) — your overrides take effect
15
+ * automatically across the entire UI.
16
+ *
17
+ * TOKEN GROUPS:
18
+ * - Base / surface : --background, --foreground, --card, --card-foreground
19
+ * - Brand : --primary, --secondary, --accent (+ -foreground pairs)
20
+ * - Semantic : --success, --warning, --error, --info (+ -foreground pairs)
21
+ * - Neutral : --muted, --muted-foreground, --border, --input, --ring
22
+ * - Shape : --radius
23
+ *
24
+ * COLOR SPACE: OKLCH (lightness chroma hue)
25
+ * oklch(<L 0–1> <C 0–0.4> <H 0–360>)
26
+ * L=0.5 is perceptually mid-gray; C=0 is achromatic.
27
+ *
28
+ * ============================================================
29
+ */
30
+
31
+ :root {
32
+ /* === Base / Surface === */
33
+ --background: oklch(0.98 0.003 250); /* Page background */
34
+ --foreground: oklch(0.25 0.04 240); /* Default text */
35
+
36
+ --card: oklch(1 0 0); /* Card / panel background */
37
+ --card-foreground: oklch(0.25 0.04 240); /* Card text */
38
+
39
+ /* === Brand Colors === */
40
+ /* Replace these three pairs with your brand palette */
41
+ --primary: oklch(0.45 0.15 142); /* Primary brand color */
42
+ --primary-foreground: oklch(0.98 0.01 55);
43
+
44
+ --secondary: oklch(0.75 0.18 85); /* Secondary brand color */
45
+ --secondary-foreground: oklch(0.25 0.04 240);
46
+
47
+ --accent: oklch(0.82 0.2 85); /* Accent / CTA color */
48
+ --accent-foreground: oklch(0.25 0.04 240);
49
+
50
+ /* === Semantic Colors === */
51
+ /* Adjust hue/chroma to match your brand tone while preserving
52
+ lightness levels so contrast ratios stay accessible (WCAG AA). */
53
+ --success: oklch(0.65 0.18 145);
54
+ --success-foreground: oklch(0.98 0.01 145);
55
+
56
+ --warning: oklch(0.75 0.15 75);
57
+ --warning-foreground: oklch(0.25 0.04 75);
58
+
59
+ --error: oklch(0.58 0.22 27);
60
+ --error-foreground: oklch(0.98 0.01 27);
61
+
62
+ --info: oklch(0.6 0.15 240);
63
+ --info-foreground: oklch(0.98 0.01 240);
64
+
65
+ /* === Neutral / Chrome === */
66
+ --muted: oklch(0.92 0.01 240); /* Muted backgrounds */
67
+ --muted-foreground: oklch(0.55 0.03 240); /* Muted / placeholder text */
68
+ --border: oklch(0.93 0.01 240); /* Dividers and borders */
69
+ --input: oklch(1 0 0); /* Input field background */
70
+ --ring: oklch(0.82 0.2 85); /* Focus ring (usually = --accent) */
71
+
72
+ /* === Shape === */
73
+ --radius: 0.75rem; /* Base border-radius; used by --radius-{sm,md,lg,xl} */
74
+ }
75
+
76
+ /* ============================================================
77
+ * DARK MODE OVERRIDES
78
+ * Applied when the <html> (or any ancestor) has class="dark".
79
+ * Convention in this project: @custom-variant dark (&:is(.dark *))
80
+ * ============================================================ */
81
+ .dark {
82
+ /* === Base / Surface === */
83
+ --background: oklch(0.18 0.04 240);
84
+ --foreground: oklch(0.95 0.01 55);
85
+
86
+ --card: oklch(0.22 0.04 240);
87
+ --card-foreground: oklch(0.95 0.01 55);
88
+
89
+ /* === Brand Colors (dark-adjusted) === */
90
+ /* In dark mode, brand colors typically shift to higher lightness
91
+ so they stand out against dark backgrounds. */
92
+ --primary: oklch(0.75 0.18 85);
93
+ --primary-foreground: oklch(0.25 0.04 240);
94
+
95
+ --secondary: oklch(0.55 0.12 142);
96
+ --secondary-foreground: oklch(0.95 0.01 55);
97
+
98
+ --accent: oklch(0.85 0.22 85);
99
+ --accent-foreground: oklch(0.25 0.04 240);
100
+
101
+ /* === Semantic Colors (dark-adjusted) === */
102
+ --success: oklch(0.7 0.2 145);
103
+ --success-foreground: oklch(0.18 0.04 145);
104
+
105
+ --warning: oklch(0.8 0.18 75);
106
+ --warning-foreground: oklch(0.2 0.04 75);
107
+
108
+ --error: oklch(0.65 0.25 27);
109
+ --error-foreground: oklch(0.18 0.04 27);
110
+
111
+ --info: oklch(0.7 0.18 240);
112
+ --info-foreground: oklch(0.18 0.04 240);
113
+
114
+ /* === Neutral / Chrome === */
115
+ --muted: oklch(0.3 0.04 240);
116
+ --muted-foreground: oklch(0.7 0.03 240);
117
+ --border: oklch(0.27 0.04 240);
118
+ --input: oklch(0.22 0.04 240);
119
+ --ring: oklch(0.85 0.22 85);
120
+
121
+ /* --radius is theme-independent; no override needed */
122
+ }