th-lonely-universe-web-lib
v0.0.5
Published
component for lonely universe web
Readme
th-lonely-universe-web-lib
A Svelte 5 UI component library with Tailwind CSS 4 and DaisyUI, built for the Lonely Universe web ecosystem.
Tech Stack
- Svelte 5 (runes mode:
$props(),$state(),$derived(),$effect()) - SvelteKit with
@sveltejs/adapter-static - Tailwind CSS 4 (CSS-first config via
@tailwindcss/vite) - DaisyUI 5 (plugin via
@plugin "daisyui") - TypeScript
- Vitest (unit tests) + Playwright (integration tests)
Getting Started
npm install
npm run dev # Start dev server
npm run build # Build static site
npm run package # Build library package (dist/)
npm run check # Run svelte-check
npm run test:unit # Run unit testsInstallation (as dependency)
npm install th-lonely-universe-web-libTheme Setup
Import the theme CSS in your app's root CSS or layout:
@import "tailwindcss";
@import "th-lonely-universe-web-lib/theme/app.css";Or import individual theme files:
@import "th-lonely-universe-web-lib/theme/theme.css";
@import "th-lonely-universe-web-lib/theme/safelist.css";Package Exports
| Export Path | Description |
|---|---|
| ./svelte/ui or . or ./ui | All UI components + enums |
| ./svelte/async | AsyncLoading component |
| ./svelte/analytics | Analytics tracking components |
| ./async | Future, Ask utilities |
| ./fp | Either (functional programming) |
| ./blizzard | HTTP client |
| ./auth | Auth provider |
| ./cache | LocalStorage, MemCache |
| ./store | Svelte store utilities |
| ./message-bus | Pub/sub message bus |
| ./queue | Task queue |
| ./i18n | Translator plugin |
| ./lang-ext | Language extensions (noop, done, enum) |
| ./analytics | Analytics core (native bridge) |
| ./theme/app.css | Full theme stylesheet |
| ./theme/theme.css | Color/breakpoint/font tokens |
| ./theme/safelist.css | Safelist for dynamic classes |
| ./theme/tailwind.config.js | Tailwind config helper |
UI Components
All UI components use Svelte 5 runes syntax. Import from th-lonely-universe-web-lib/svelte/ui or th-lonely-universe-web-lib.
Layout
Layout.svelte
Base layout wrapper.
<script lang="ts">
import { Layout } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<Layout>
<!-- content -->
</Layout>Box
HBox.svelte / VBox.svelte
Horizontal and vertical flexbox containers.
Props: id, horizontalAlign, verticalAlign, gapSize, itemSpread, custom, children (Snippet), onscroll
<script lang="ts">
import { HBox, VBox, GapSize, HorizontalAlign, VerticalAlign } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<HBox gapSize={GapSize['16px']} horizontalAlign={HorizontalAlign.Center}>
<Button>Left</Button>
<Button>Right</Button>
</HBox>
<VBox gapSize={GapSize['8px']} verticalAlign={VerticalAlign.Top}>
<TextField placeholder="Username" />
<TextField placeholder="Password" />
</VBox>Button
Button.svelte
Customizable button with multiple styles, variants, and sizes.
Props: id, style: ButtonStyle, variant: ButtonVariant, size: ButtonSize, type, disabled, custom, onclick, onmousedown, children (Snippet)
<script lang="ts">
import { Button, ButtonStyle, ButtonVariant, ButtonSize } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<Button style={ButtonStyle.Primary} variant={ButtonVariant.Positive} size={ButtonSize.Large}>
Save
</Button>Text
Text.svelte
Typography component with style, color, alignment, and wrapping options.
Props: style: TextStyle, color: TextColor, align: TextAlign, wrap: TextWrap, spacing: TextSpacing, opacity: TextOpacity, whitespace: TextWhitespace, decorationLine: TextDecorationLine, custom, onclick, children (Snippet)
<script lang="ts">
import { Text, TextStyle, TextColor } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<Text style={TextStyle.H3} color={TextColor.Primary300}>Hello</Text>Icon
Icon.svelte
Material icon display with size, color, and style.
Props: custom, style: IconStyle, name: IconName, size: IconSize, color
<script lang="ts">
import { Icon, IconName, IconSize, IconStyle } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<Icon name={IconName.Home} size={IconSize.md24} style={IconStyle.Outlined} color="text-primary-300" />Card
Card.svelte
Container with border, background, and padding.
Props: borderColor, bgColor, rounded, padding, custom, onclick, children (Snippet)
<Card bgColor="bg-gray-50" rounded="rounded-lg">
<Text>Content here</Text>
</Card>Chip
Chip.svelte
Small rounded label for tags, filters, or selections.
Props: bgColor, width, custom, round, children (Snippet)
<Chip bgColor="bg-blue-200">Active</Chip>Image
Image.svelte
Image display with configurable size, scaling, and fallback.
Props: id, src, width: ImageSize, height: ImageSize, scaling: ImageScaling, borderRadius: ImageBorderRadius, custom, defaultImage
<script lang="ts">
import { Image, ImageSize, ImageBorderRadius } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<Image src="/avatar.png" width={ImageSize.Medium} borderRadius={ImageBorderRadius.Circle} />Input
InputField.svelte
Text input with label, validation, and icon support.
Props: id, required, label, hasInfoIcon, onInfoClick, sideLabel, type: TextFieldType, mode: TextFieldMode, step, value (bindable), pattern, minLength, maxLength, placeholder, disabled, autofocus, leftIconName, rightIconName, unit, requiredMsg, errMsg, onInput, onFocusIn, onFocusOut, onLeftIconClick, onRightIconClick, custom, onkeyup, onkeydown
<InputField label="Username" type="text" required={true} requiredMsg="Required" />TextField.svelte
Low-level text input with full control over events and state.
Props: id, type, mode, step, value (bindable), pattern, minLength, maxLength, placeholder, required, disabled, autofocus, leftIconName, rightIconName, unit, requiredMsg, errMsg, onInput, onFocusIn, onFocusOut, onLeftIconClick, onRightIconClick, custom, onkeyup, onkeydown
TextArea.svelte
Multi-line text input with label and validation.
Props: id, value (bindable), label, minLength, maxLength, placeholder, required, disabled, autofocus, resize, width, height, requiredMsg, errMsg, onInput, onFocusIn, onFocusOut, custom, onkeyup, onkeydown
TextAreaResizable.svelte
Resizable contenteditable text area.
Props: Same as TextArea.
InputNumberStepper.svelte
Number input with increment/decrement buttons.
Props: id, value (bindable), onChange, min, max, maxLength, custom, step
<InputNumberStepper value={5} min={1} max={10} step={1} />TextLabel.svelte
Label component for form fields.
Props: forId, label, required, hasInfoIcon, onInfoClick, sideLabel, custom, onclick, children (Snippet)
Modal
Modal.svelte
Base modal dialog.
Props: id, isDialogVisible (bindable), round, width, padding, children (Snippet)
<Modal bind:isDialogVisible={showModal}>
<Text>Modal content</Text>
</Modal>ActionModal.svelte
Modal with icon, title, description, and action button.
Props: id, isDialogVisible (bindable), iconName, iconStyle, iconColor, title, subTitle, desc, footer, primaryBtnCaption, primaryBtnStyle, primaryBtnVariant, primaryBtnSize, primaryBtnType, primaryBtnDisabled, onPrimaryBtnClick
InfoModal / SuccessModal / FailureModal / WarnModal / ConfirmationModal
Pre-configured variants of ActionModal for common use cases.
Navigation
TopNavBar.svelte
Top navigation bar with title, left/right icons.
Props: id, variant, title, img, leftIconName, onLeftIconClick, rightIconName, onRightIconClick, custom, customTxtTitle, children (Snippet)
<TopNavBar title="My App" leftIconName={IconName.Menu} onLeftIconClick={() => goto('/')} />StickyTopBar.svelte / StickyBottomBar.svelte
Sticky positioned bars.
Props: custom, children (Snippet)
StepperInput.svelte
Stepper input with +/- buttons.
Props: id, value (bindable), size, variant, min, step, isAutoAdjustment, onIncrease, onDecrease
Tab
Tab.svelte
Tab container with style context.
Props: id, style: TabStyle, custom, children (Snippet)
TabItem.svelte
Individual tab item.
Props: id, title, custom, open (bindable), extension (Snippet), body (Snippet)
<Tab style={TabStyle.Primary}>
<TabItem title="Tab 1">
{#snippet body()}
<Text>Content 1</Text>
{/snippet}
</TabItem>
</Tab>Toast
Toast.svelte
Toast notification component (managed via toast store).
<script lang="ts">
import { Toast, toast } from 'th-lonely-universe-web-lib/svelte/ui'
</script>
<Toast />
<!-- Trigger toast -->
<Button onclick={() => toast.success('Done!')}>Show Toast</Button>Loading
Loading.svelte
Spinning SVG loading indicator.
Props: id, width, height, custom
LoadingModal.svelte
Modal dialog with loading spinner.
Props: id, isDialogVisible, msg
Other
Spacer.svelte
Spacer for layout gaps.
Props: gapSpace: GapSpace, style: SpacerStyle, custom
HtmlDisplay.svelte
Renders raw HTML content.
Props: html, preserveStyle, custom
PlaySoundOnEvent.svelte
Plays sound on DOM events.
Props: soundPath, DOMEvent, targetElementId, children (Snippet with onEventSoundPlayer)
Async Utilities
Future
Composable abstraction for typed async operations.
import { Future } from 'th-lonely-universe-web-lib/async'
const result = Future.fromPromise(fetchData())
.map(data => transform(data))
.onSuccess(result => console.log(result))
.onError(error => console.error(error))AsyncLoading.svelte
Manages async state (idle/pending/success/failed) in the UI using Svelte 5 snippets.
<script lang="ts">
import AsyncLoading, { StateChange } from 'th-lonely-universe-web-lib/svelte/async'
import { Future } from 'th-lonely-universe-web-lib/async'
const stateChange = StateChange.future(myFuture)
</script>
<AsyncLoading useDefaultLoading={true} {stateChange}>
{#snippet success({ result })}
<Text>Done: {result}</Text>
{/snippet}
{#snippet failed({ error })}
<Text>Error: {error}</Text>
{/snippet}
</AsyncLoading>Analytics
TrackContentView.svelte
Logs analytics events on mount.
<script lang="ts">
import TrackContentView from 'th-lonely-universe-web-lib/svelte/analytics'
</script>
<TrackContentView events={[{ name: 'page_view', payload: {}, platform: 'google' }]} />TrackUserAction.svelte
Tracks user interactions on DOM events using Svelte 5 snippets.
<TrackUserAction events={events} DOMEvent="click">
{#snippet children({ targetElementId })}
<button id={targetElementId}>Click me</button>
{/snippet}
</TrackUserAction>Theme Customization
The theme is defined in CSS-first format (Tailwind CSS 4):
src/lib/theme/theme.css— Color tokens, breakpoints, font sizes via@theme {}src/lib/theme/safelist.css— Explicit classes for dynamic usagesrc/lib/theme/app.css— Main entry point with@import "tailwindcss",@plugin "daisyui",@sourcesrc/lib/theme/custom/— Custom CSS (shadows, error styles)
Color Palette
| Token | Example |
|---|---|
| primary-50 to primary-500 | Pink/Rose tones |
| secondary-50 to secondary-500 | Hot pink tones |
| grey-50 to grey-500 | Neutral greys |
| success-50 to success-300 | Green tones |
| warning-50 to warning-300 | Orange/amber tones |
| danger-50 to danger-300 | Red tones |
Project Structure
src/
lib/
analytics/ # Analytics core (native bridge)
async/ # Future, Ask utilities
auth/ # Auth provider, session management
blizzard/ # HTTP client
cache/ # LocalStorage, MemCache
fp/ # Either (functional programming)
i18n/ # Translator plugin
lang-ext/ # Language extensions
message-bus/ # Pub/sub message bus
queue/ # Task queue
store/ # Svelte store utilities
svelte/
analytics/ # TrackContentView, TrackUserAction
async/ # AsyncLoading
ui/ # All UI components
box/ button/ card/ chip/
html-display/ icon/ image/ input/
layout/ loading/ modal/ navigation-bar/
play-sound-on-event/ spacer/ tab/ text/
toast/
theme/ # Tailwind CSS 4 theme (app.css, theme.css, safelist.css)
routes/ # Demo/showcase pagesLicense
MIT
