@lavalogic/scoria 0.38.8 → 0.38.10

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,65 @@
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">
4
+ import { Size } from '../Types/Internal/Size.js';
5
+ import Icon from './Icon.svelte';
6
+ import type { InfoAlertProps } from './InfoAlertProps.js';
7
+
8
+ const { children, iconName = 'circle-information' }: InfoAlertProps = $props();
9
+ </script>
10
+
11
+ <!--
12
+ Small, inline informational banner. Mirrors the structure of the
13
+ `.error-banner` block already used inside the Table Configuration
14
+ modal - leading icon + body text on a tinted background - but on a
15
+ neutral blue palette so it reads as "helper text" rather than "error".
16
+
17
+ The body is a snippet so callers can inline links or emphasis without
18
+ the component prescribing a content shape.
19
+ -->
20
+ <div
21
+ class="info-alert"
22
+ role="status"
23
+ >
24
+ <div class="icon">
25
+ <Icon
26
+ name={iconName}
27
+ size={Size.Small}
28
+ />
29
+ </div>
30
+ <div class="body">
31
+ {@render children()}
32
+ </div>
33
+ </div>
34
+
35
+ <style>.info-alert {
36
+ display: flex;
37
+ flex-flow: row nowrap;
38
+ align-items: flex-start;
39
+ gap: 0.5rem;
40
+ padding: 0.625rem 0.875rem;
41
+ border: solid 1px #cbd4da;
42
+ border-radius: 4px;
43
+ background-color: #f4f7f9;
44
+ color: #3a4952;
45
+ font-size: 1.125rem;
46
+ line-height: 1.4;
47
+ }
48
+
49
+ /* Nudge the icon down a hair so it sits visually centred against
50
+ the first line of body text rather than aligned to the very top
51
+ of the first character ascent. */
52
+ .icon {
53
+ display: flex;
54
+ align-items: center;
55
+ flex-shrink: 0;
56
+ padding-top: 0.0625rem;
57
+ color: #647d8e;
58
+ --colour: #647d8e;
59
+ }
60
+
61
+ .body {
62
+ flex: 1 1 auto;
63
+ min-width: 0;
64
+ color: #647d8e;
65
+ }</style>
@@ -0,0 +1,4 @@
1
+ import type { InfoAlertProps } from './InfoAlertProps.js';
2
+ declare const InfoAlert: import("svelte").Component<InfoAlertProps, {}, "">;
3
+ type InfoAlert = ReturnType<typeof InfoAlert>;
4
+ export default InfoAlert;
@@ -0,0 +1,24 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { icons } from './Icons.js';
3
+ /**
4
+ * Props for `InfoAlert` - the small, inline informational banner used
5
+ * for non-blocking helper text and empty-state messages (e.g. "you
6
+ * have not saved any layouts yet…", "no filters match the search…").
7
+ *
8
+ * Visually it mirrors the existing `.error-banner` pattern used inside
9
+ * scoria's modals - an icon plus a single line / paragraph of body
10
+ * text on a tinted background - but with neutral / informational
11
+ * colours rather than error-red. It is deliberately a thin shell: any
12
+ * inline links or `<strong>` accents go inside the default snippet.
13
+ */
14
+ export interface InfoAlertProps {
15
+ /** Body of the alert, rendered to the right of the leading icon. */
16
+ children: Snippet;
17
+ /**
18
+ * Optional icon name override. Defaults to `circle-information`,
19
+ * the standard neutral-info glyph; pass another name from the
20
+ * frozen `icons` registry to fit a more specific empty-state visual
21
+ * (e.g. `circle-exclamation` for a gentle warning).
22
+ */
23
+ iconName?: keyof typeof icons;
24
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -17,7 +17,6 @@
17
17
 
18
18
  const { columnDef }: ColumnListRowProps<T> = $props();
19
19
 
20
-
21
20
  /**
22
21
  * Position of this column inside the sorted column list. Drives the
23
22
  * disabled state of the "move up" / "move down" buttons and supplies
@@ -507,6 +506,14 @@ li.single-column:not(.anchor):last-of-type {
507
506
  display: flex;
508
507
  flex-shrink: 0;
509
508
  }
509
+ .visibility-wrapper :global(div.inner-checkbox-container) {
510
+ border-width: 1px;
511
+ border-color: #cbd4da;
512
+ }
513
+ .visibility-wrapper :global(.outer-checkbox-container:hover div.inner-checkbox-container:not(.disabled)) {
514
+ border-width: 1px;
515
+ border-color: #adbbc5;
516
+ }
510
517
 
511
518
  .pin-selector {
512
519
  --input-height: 2.25rem;
@@ -519,6 +526,12 @@ li.single-column:not(.anchor):last-of-type {
519
526
  .pin-selector.disabled {
520
527
  opacity: 0.5;
521
528
  }
529
+ .pin-selector :global(.radios > label) {
530
+ padding: 0;
531
+ }
532
+ .pin-selector :global(.radios > label:first-child) {
533
+ border-left: none;
534
+ }
522
535
 
523
536
  .column-label {
524
537
  width: 100%;
@@ -7,6 +7,7 @@
7
7
  import Button from '../../Button.svelte';
8
8
  import DesktopModal from '../../DesktopModal.svelte';
9
9
  import Icon from '../../Icon.svelte';
10
+ import InfoAlert from '../../InfoAlert.svelte';
10
11
  import MultiSelect from '../../MultiSelect.svelte';
11
12
  import { cssLength } from '../../../Helpers/Helpers.svelte.js';
12
13
  import { ColourSet } from '../../../scss/colours.js';
@@ -226,7 +227,7 @@
226
227
 
227
228
  <div class="picker">
228
229
  {#if loadingUsers && allUsers === null}
229
- <p class="muted">Loading users…</p>
230
+ <InfoAlert>Loading users…</InfoAlert>
230
231
  {:else if allUsers !== null}
231
232
  <MultiSelect
232
233
  label="Users"
@@ -244,11 +245,11 @@
244
245
  </div>
245
246
 
246
247
  {#if selected.length === 0}
247
- <p class="muted">
248
+ <InfoAlert>
248
249
  No users selected. Use the picker above to share this {view.kind === 'filter'
249
250
  ? 'filter'
250
251
  : 'layout'} with one or more users.
251
- </p>
252
+ </InfoAlert>
252
253
  {:else}
253
254
  <ul class="user-card-list">
254
255
  {#each selected as user (user.id)}
@@ -315,11 +316,6 @@
315
316
  flex-flow: column nowrap;
316
317
  }
317
318
 
318
- .muted {
319
- color: #647d8e;
320
- margin: 0;
321
- }
322
-
323
319
  .user-card-list {
324
320
  list-style: none;
325
321
  margin: 0;
@@ -8,6 +8,7 @@
8
8
  import DesktopModal from '../../DesktopModal.svelte';
9
9
  import HorizontalTabGroup from '../../HorizontalTabGroup.svelte';
10
10
  import Icon from '../../Icon.svelte';
11
+ import InfoAlert from '../../InfoAlert.svelte';
11
12
  import TextInput from '../../TextInput.svelte';
12
13
  import VerticalTabGroup from '../../VerticalTabGroup.svelte';
13
14
  import { cssLength } from '../../../Helpers/Helpers.svelte.js';
@@ -336,12 +337,12 @@
336
337
 
337
338
  {#if args.tab === 'mine'}
338
339
  {#if loadingViews}
339
- <p class="muted">Loading saved {sectionNounPlural.toLowerCase()}…</p>
340
+ <InfoAlert>Loading saved {sectionNounPlural.toLowerCase()}…</InfoAlert>
340
341
  {:else if myViews.length === 0}
341
- <p class="muted">
342
+ <InfoAlert>
342
343
  You have not saved any {sectionNounPlural.toLowerCase()} yet. Use the "Save a new {sectionNoun}"
343
344
  tab to create one.
344
- </p>
345
+ </InfoAlert>
345
346
  {:else}
346
347
  <ul class="card-list">
347
348
  {#each myViews as view (view.id)}
@@ -421,9 +422,9 @@
421
422
 
422
423
  {#if publicViews !== null}
423
424
  {#if publicViews.length === 0}
424
- <p class="muted">
425
+ <InfoAlert>
425
426
  There are no further {sectionNounPlural.toLowerCase()} available to subscribe to.
426
- </p>
427
+ </InfoAlert>
427
428
  {:else}
428
429
  <ul class="card-list">
429
430
  {#each publicViews as view (view.id)}
@@ -449,9 +450,9 @@
449
450
  {/if}
450
451
 
451
452
  {#if sharedViews.length === 0}
452
- <p class="muted">
453
+ <InfoAlert>
453
454
  No {sectionNounPlural.toLowerCase()} are currently shared with you.
454
- </p>
455
+ </InfoAlert>
455
456
  {:else}
456
457
  <ul class="card-list">
457
458
  {#each sharedViews as view (view.id)}
@@ -484,29 +485,37 @@
484
485
  {/if}
485
486
  {:else}
486
487
  <div class="save-tab">
487
- <p class="muted">
488
+ <InfoAlert>
488
489
  Save the table's current {sectionNoun.toLowerCase()} as a reusable named
489
490
  {sectionNoun.toLowerCase()}.
490
- </p>
491
- <TextInput
492
- placeholder={`${sectionNoun} name`}
493
- bind:value={newViewName}
494
- onkeydown={(e: KeyboardEvent) => {
495
- if (e.key === 'Enter') {
496
- e.preventDefault();
497
- saveNewView();
498
- }
499
- }}
500
- />
501
- <!-- Wrap the button in a row so the flex column's default
502
- `align-items: stretch` does not blow it up to the input's
503
- width. The row itself can stretch; the button inside sits
504
- at its natural content width like every other Button. -->
505
- <div class="save-tab-actions">
506
- <Button
507
- disabled={!newViewName.trim()}
508
- onclick={saveNewView}>Save Current</Button
509
- >
491
+ </InfoAlert>
492
+ <!-- The InfoAlert above spans the full tab body so the
493
+ empty-state visuals are consistent across all three tabs.
494
+ The name input + Save button below stay grouped in a
495
+ narrower form column (`.save-tab-form`) so they keep
496
+ comfortable form proportions instead of stretching across
497
+ the whole 50vw modal. -->
498
+ <div class="save-tab-form">
499
+ <TextInput
500
+ placeholder={`${sectionNoun} name`}
501
+ bind:value={newViewName}
502
+ onkeydown={(e: KeyboardEvent) => {
503
+ if (e.key === 'Enter') {
504
+ e.preventDefault();
505
+ saveNewView();
506
+ }
507
+ }}
508
+ />
509
+ <!-- Wrap the button in a row so the flex column's default
510
+ `align-items: stretch` does not blow it up to the input's
511
+ width. The row itself can stretch; the button inside sits
512
+ at its natural content width like every other Button. -->
513
+ <div class="save-tab-actions">
514
+ <Button
515
+ disabled={!newViewName.trim()}
516
+ onclick={saveNewView}>Save Current</Button
517
+ >
518
+ </div>
510
519
  </div>
511
520
  </div>
512
521
  {/if}
@@ -625,10 +634,6 @@
625
634
  background-color: #ffffff;
626
635
  }
627
636
 
628
- .muted {
629
- color: #647d8e;
630
- }
631
-
632
637
  .card-list {
633
638
  list-style: none;
634
639
  margin: 0;
@@ -694,10 +699,24 @@
694
699
  margin-bottom: 0.5rem;
695
700
  }
696
701
 
702
+ /* Outer Save-tab container. Spans the full tab body so the InfoAlert
703
+ matches the empty-state alert width in My-Layouts / Shared-Layouts.
704
+ The narrower form column (input + Save button) lives one level
705
+ deeper in `.save-tab-form`. */
697
706
  .save-tab {
698
707
  display: flex;
699
708
  flex-flow: column nowrap;
700
709
  gap: 0.75rem;
710
+ }
711
+
712
+ /* Form column for the layout-name input and Save Current button.
713
+ `max-width` keeps the input at a comfortable form width rather
714
+ than stretching across the full modal; the button below sits on
715
+ the same column so the two read as a single form unit. */
716
+ .save-tab-form {
717
+ display: flex;
718
+ flex-flow: column nowrap;
719
+ gap: 0.75rem;
701
720
  max-width: 24rem;
702
721
  }
703
722
 
package/dist/index.d.ts CHANGED
@@ -54,6 +54,8 @@ export type { HorizontalTabGroupProps } from './Components/HorizontalTabGroupPro
54
54
  export { default as Icon } from './Components/Icon.svelte';
55
55
  export { type IconProps } from './Components/IconProps.js';
56
56
  export { icons } from './Components/Icons.js';
57
+ export { default as InfoAlert } from './Components/InfoAlert.svelte';
58
+ export type { InfoAlertProps } from './Components/InfoAlertProps.js';
57
59
  export type { InputProps } from './Components/InputProps.js';
58
60
  export { default as LoadingAnimation } from './Components/LoadingAnimation.svelte';
59
61
  export type { LoadingAnimationProps } from './Components/LoadingAnimationProps.js';
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ export { default as HorizontalTabGroup } from './Components/HorizontalTabGroup.s
35
35
  export { default as Icon } from './Components/Icon.svelte';
36
36
  export {} from './Components/IconProps.js';
37
37
  export { icons } from './Components/Icons.js';
38
+ export { default as InfoAlert } from './Components/InfoAlert.svelte';
38
39
  export { default as LoadingAnimation } from './Components/LoadingAnimation.svelte';
39
40
  export { default as LoadingModal } from './Components/LoadingModal.svelte';
40
41
  export { default as LoadingOverlay } from './Components/LoadingOverlay.svelte';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lavalogic/scoria",
3
3
  "description": "Svelte components used for the FloWMS Web Frontend",
4
- "version": "0.38.8",
4
+ "version": "0.38.10",
5
5
  "publishConfig": {
6
6
  "access": "restricted"
7
7
  },