@dodlhuat/basix 1.3.3 → 1.3.5

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,4 +1,4 @@
1
- # Basix 1.3.3
1
+ # Basix 1.3.5
2
2
 
3
3
  Basix is intended as a starter for the rapid development of a design. Each design element can be added individually to
4
4
  include only the data required. It is using plain javascript / typescript and therefore is not dependent on any plugin.
@@ -830,25 +830,91 @@ new CodeViewer('#output', '.card { padding: 1rem; }', 'css');
830
830
 
831
831
  ### Editor
832
832
 
833
- The Editor component provides a contenteditable rich-text editing area with undo/redo, word count, and an optional side panel showing the raw HTML source and a live preview. Requires a `#editable` element in the DOM.
833
+ The Editor component provides a contenteditable rich-text editing area with undo/redo, word count, and an optional side panel showing the raw HTML source and a live preview. Internal elements are located by `data-editor` attributes scoped to a `root` container no globally unique IDs required, which makes multiple editors on the same page possible.
834
834
 
835
835
  ``` html
836
- <div id="editable" contenteditable="true"></div>
837
- <!-- Optional side panel elements -->
838
- <textarea id="code"></textarea>
839
- <div id="preview"></div>
840
- <div id="sidePanel"></div>
841
- <span id="wordCount"></span>
836
+ <div class="editor" id="my-editor">
837
+ <div class="editor-toolbar">
838
+ <button data-editor-action="undo" title="Undo">↩</button>
839
+ <button data-editor-action="redo" title="Redo">↪</button>
840
+ <button data-cmd="bold">B</button>
841
+ <button data-cmd="italic">I</button>
842
+ <button data-editor-action="link">Link</button>
843
+ <!-- … -->
844
+ </div>
845
+ <div class="editor-body">
846
+ <div class="editor-main">
847
+ <div data-editor="editable" class="editable" contenteditable="true"></div>
848
+ </div>
849
+ <!-- Full mode: add side panel with code + preview -->
850
+ <div data-editor="side-panel" class="editor-side">
851
+ <div class="side-tabs">
852
+ <button class="side-tab active" data-tab="code-panel">HTML</button>
853
+ <button class="side-tab" data-tab="preview-panel">Preview</button>
854
+ </div>
855
+ <div class="side-panels">
856
+ <div class="side-panel active" data-editor="code-panel">
857
+ <textarea data-editor="code"></textarea>
858
+ </div>
859
+ <div class="side-panel" data-editor="preview-panel">
860
+ <div data-editor="preview" class="preview-content"></div>
861
+ </div>
862
+ </div>
863
+ </div>
864
+ </div>
865
+ <div class="editor-footer">
866
+ <span data-editor="wordcount">0 words</span>
867
+ </div>
868
+ </div>
842
869
  ```
843
870
 
844
871
  ``` js
845
- // Full editor with side panel
846
- new Editor();
872
+ // Single editor
873
+ new Editor({ root: '#my-editor' });
874
+
875
+ // Simple mode — only requires [data-editor="editable"], hides the side panel
876
+ new Editor({ root: '#my-editor', simple: true });
877
+
878
+ // Multiple editors on the same page
879
+ const editor1 = new Editor({ root: '#editor-1' });
880
+ const editor2 = new Editor({ root: '#editor-2' });
847
881
 
848
- // Simple mode — hides the side panel permanently
849
- new Editor({ simple: true });
882
+ editor1.destroy();
850
883
  ```
851
884
 
885
+ #### Options
886
+
887
+ | Option | Type | Default | Description |
888
+ |---|---|---|---|
889
+ | `root` | string \| HTMLElement | `document.body` | Root container. Required when multiple editors coexist on the same page. |
890
+ | `simple` | boolean | `false` | Simple mode requires only `[data-editor="editable"]`. Full mode additionally requires `code`, `preview`, `side-panel`, `code-panel`, and `preview-panel` elements. |
891
+
892
+ #### `data-editor` elements
893
+
894
+ | Value | Element | Required |
895
+ |---|---|---|
896
+ | `editable` | `contenteditable` div — the writing area | always |
897
+ | `code` | `<textarea>` — HTML source view | full mode |
898
+ | `preview` | `<div>` — live preview | full mode |
899
+ | `side-panel` | Side panel container | full mode |
900
+ | `code-panel` | Code tab panel (matches `data-tab="code-panel"`) | full mode |
901
+ | `preview-panel` | Preview tab panel | full mode |
902
+ | `wordcount` | Word count display | optional |
903
+ | `image-file` | `<input type="file">` for image insertion | optional |
904
+
905
+ #### `data-editor-action` buttons
906
+
907
+ | Value | Description |
908
+ |---|---|
909
+ | `undo` | Triggers undo |
910
+ | `redo` | Triggers redo |
911
+ | `link` | Opens URL prompt for link insertion |
912
+ | `image` | Triggers the image file picker |
913
+ | `save` | Downloads content as an HTML file (Ctrl+S) |
914
+ | `clear` | Clears all content |
915
+ | `clean` | Strips formatting from the current selection |
916
+ | `toggle-code` | Shows / hides the HTML side panel |
917
+
852
918
  ### Custom Scrollbar
853
919
 
854
920
  The Scrollbar component creates custom-styled scrollbars. Supports pointer/touch dragging, track clicking, and automatic thumb sizing. Can be used with any class.
package/css/badge.scss CHANGED
@@ -97,3 +97,11 @@
97
97
  &.badge-error { background: var(--error); }
98
98
  }
99
99
  }
100
+
101
+ [data-theme="dark"] {
102
+ .badge-solid {
103
+ &.badge-success { color: var(--background); }
104
+ &.badge-warning { color: var(--background); }
105
+ &.badge-error { color: var(--background); }
106
+ }
107
+ }
package/css/button.scss CHANGED
@@ -60,7 +60,7 @@ button,
60
60
  }
61
61
 
62
62
  &.active {
63
- background: var(--divider);
63
+ background: var(--accent-color-tint);
64
64
  color: var(--accent-color);
65
65
  }
66
66
 
@@ -172,29 +172,75 @@ button.button-error {
172
172
 
173
173
  .button-success,
174
174
  button.button-success {
175
- @include button-variant-dark(var(--success));
175
+ color: var(--background);
176
+ &:hover:not(:disabled) { background: color-mix(in srgb, var(--success) 82%, white); }
177
+ &:active:not(:disabled) { background: color-mix(in srgb, var(--success) 70%, white); }
178
+ &.is-loading::after { color: var(--background); }
176
179
  }
177
180
 
178
181
  .button-warning,
179
182
  button.button-warning {
180
- @include button-variant-dark(var(--warning));
183
+ color: var(--background);
184
+ &:hover:not(:disabled) { background: color-mix(in srgb, var(--warning) 82%, white); }
185
+ &:active:not(:disabled) { background: color-mix(in srgb, var(--warning) 70%, white); }
186
+ &.is-loading::after { color: var(--background); }
181
187
  }
182
188
 
183
189
  .button-error,
184
190
  button.button-error {
185
- @include button-variant-dark(var(--error));
191
+ color: var(--background);
192
+ &:hover:not(:disabled) { background: color-mix(in srgb, var(--error) 82%, white); }
193
+ &:active:not(:disabled) { background: color-mix(in srgb, var(--error) 70%, white); }
194
+ &.is-loading::after { color: var(--background); }
186
195
  }
187
196
 
188
- .button-primary,
189
- button.button-primary,
190
- .button-success,
191
- button.button-success,
192
- .button-warning,
193
- button.button-warning,
194
- .button-error,
195
- button.button-error {
196
- &.is-loading::after {
197
- color: var(--primary-text);
198
- }
197
+ .button-primary.is-loading::after,
198
+ button.button-primary.is-loading::after {
199
+ color: var(--primary-text);
200
+ }
201
+ }
202
+
203
+ // Size variants
204
+ .button-sm,
205
+ button.button-sm {
206
+ padding: calc($spacing * 0.35) calc($spacing * 0.75);
207
+ font-size: 0.8125rem;
208
+ }
209
+
210
+ .button-lg,
211
+ button.button-lg {
212
+ padding: calc($spacing * 0.8) calc($spacing * 1.75);
213
+ font-size: 1.0625rem;
214
+ }
215
+
216
+ // Outline variant
217
+ .button-outline,
218
+ button.button-outline {
219
+ background: transparent;
220
+ border: 1px solid var(--divider);
221
+ color: var(--primary-text);
222
+
223
+ &:hover:not(:disabled) {
224
+ background: var(--hover);
225
+ border-color: color-mix(in srgb, var(--divider) 50%, var(--primary-text));
199
226
  }
227
+
228
+ &:active:not(:disabled) {
229
+ background: var(--secondary-background);
230
+ }
231
+ }
232
+
233
+ // Icon-only button — square, equal padding
234
+ .button-icon,
235
+ button.button-icon {
236
+ padding: calc($spacing * 0.5);
237
+ width: 2.25rem;
238
+ height: 2.25rem;
239
+ flex-shrink: 0;
240
+ }
241
+
242
+ // Pill variant
243
+ .button-pill,
244
+ button.button-pill {
245
+ border-radius: $radius-xl;
200
246
  }
package/css/chips.scss CHANGED
@@ -39,6 +39,16 @@
39
39
  outline: none;
40
40
  @include focus-glow();
41
41
  }
42
+
43
+ &.selected {
44
+ background: color-mix(in srgb, var(--accent-color) 12%, var(--background));
45
+ color: var(--accent-color);
46
+ border-color: color-mix(in srgb, var(--accent-color) 25%, transparent);
47
+
48
+ &:hover {
49
+ background: color-mix(in srgb, var(--accent-color) 18%, var(--background));
50
+ }
51
+ }
42
52
  }
43
53
 
44
54
  &.closeable {
package/css/colors.scss CHANGED
@@ -30,4 +30,8 @@ body {
30
30
 
31
31
  .default-bg {
32
32
  background: var(--divider);
33
+ }
34
+
35
+ .info-bg {
36
+ background: var(--accent-color);
33
37
  }
package/css/docs.scss CHANGED
@@ -191,10 +191,6 @@
191
191
 
192
192
  code {
193
193
  font-size: 0.8em;
194
- background: var(--secondary-background);
195
- border: 1px solid var(--divider);
196
- border-radius: 0.25rem;
197
- padding: 0.1em 0.35em;
198
194
  }
199
195
 
200
196
  .docs-demo {
package/css/dropdown.scss CHANGED
@@ -14,6 +14,20 @@
14
14
  }
15
15
  }
16
16
 
17
+ &.drop-up {
18
+ > .dropdown-menu {
19
+ top: auto;
20
+ bottom: 100%;
21
+ margin-top: 0;
22
+ margin-bottom: 6px;
23
+ transform: translateY(8px);
24
+ }
25
+
26
+ &.active > .dropdown-menu {
27
+ transform: translateY(0);
28
+ }
29
+ }
30
+
17
31
  .dropdown-menu {
18
32
  position: absolute;
19
33
  top: 100%;
package/css/modal.scss CHANGED
@@ -88,6 +88,27 @@
88
88
  }
89
89
  }
90
90
 
91
+ // Coloured variants — border echoes the type colour, close icon and header text go white
92
+ .modal-success { border-color: color-mix(in srgb, var(--success) 35%, transparent); }
93
+ .modal-error { border-color: color-mix(in srgb, var(--error) 35%, transparent); }
94
+ .modal-warning { border-color: color-mix(in srgb, var(--warning) 35%, transparent); }
95
+ .modal-info { border-color: color-mix(in srgb, var(--accent-color) 35%, transparent); }
96
+
97
+ .modal-success,
98
+ .modal-error,
99
+ .modal-warning,
100
+ .modal-info {
101
+ .close {
102
+ color: rgba(255, 255, 255, 0.8);
103
+ &:hover { color: #fff; }
104
+ }
105
+
106
+ .header {
107
+ color: #fff;
108
+ border-bottom-color: rgba(255, 255, 255, 0.2);
109
+ }
110
+ }
111
+
91
112
  @media screen and (max-width: 768px) {
92
113
  .modal-wrapper.is-visible .modal {
93
114
  transform: translateY(0);
@@ -57,6 +57,10 @@
57
57
  svg { display: block; }
58
58
  }
59
59
 
60
+ .sidebar-close {
61
+ display: none;
62
+ }
63
+
60
64
  @media (max-width: 768px) {
61
65
  .sidebar-toggle {
62
66
  display: flex;
@@ -77,4 +81,25 @@
77
81
  .sidebar-main {
78
82
  margin-left: 0;
79
83
  }
84
+
85
+ .sidebar-close {
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ position: absolute;
90
+ bottom: 1rem;
91
+ left: 50%;
92
+ transform: translateX(-50%);
93
+ background: var(--secondary-background);
94
+ border: none;
95
+ border-radius: $border-radius;
96
+ padding: 0.5rem 1.25rem;
97
+ cursor: pointer;
98
+ color: var(--primary-text);
99
+ gap: 0.4rem;
100
+ font-size: 0.875rem;
101
+ white-space: nowrap;
102
+
103
+ &:hover { background: var(--divider); }
104
+ }
80
105
  }