2 Commits

Author SHA1 Message Date
bbb6d09ecf v1.4.0
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-17 09:13:52 +00:00
2f54ee3f85 feat(elements): update design tokens and sio-fab component; bump deps and update npmextra config 2025-12-17 09:13:52 +00:00
8 changed files with 1106 additions and 325 deletions

View File

@@ -1,5 +1,13 @@
# Changelog # Changelog
## 2025-12-17 - 1.4.0 - feat(elements)
update design tokens and sio-fab component; bump deps and update npmextra config
- Refactor color tokens to a neutral HSL palette (ts_web/elements/00colors.ts) and adjust focus ring token (ts_web/elements/00tokens.ts).
- Refactor sio-fab: move styles to static property, add responsive FAB sizing and getMobileIconSize(), bind icon sizes, manage host class ('combox-open'), and tidy lifecycle methods for better behavior and mobile support.
- Bump dependencies and devDependencies: @design.estate/dees-wcctools -> ^2.0.1, lucide -> ^0.561.0; @git.zone/tsbuild -> ^4.0.2, @git.zone/tsrun -> ^2.0.1, @git.zone/tswatch -> ^2.3.13, @types/node -> ^25.0.3, etc.
- Update npmextra.json: rename configuration keys (gitzone -> @git.zone/cli, npmci -> @ship.zone/szci) and add release.registries and accessLevel for publishing.
## 2025-12-08 - 1.3.0 - feat(components) ## 2025-12-08 - 1.3.0 - feat(components)
Add reusable message input component, refactor element properties to use accessor, update styles and docs, bump dependencies Add reusable message input component, refactor element properties to use accessor, update styles and docs, bump dependencies

View File

@@ -1,5 +1,5 @@
{ {
"gitzone": { "@git.zone/cli": {
"projectType": "wcc", "projectType": "wcc",
"module": { "module": {
"githost": "gitlab.com", "githost": "gitlab.com",
@@ -9,11 +9,16 @@
"npmPackagename": "@social.io_private/catalog", "npmPackagename": "@social.io_private/catalog",
"license": "UNLICENSED", "license": "UNLICENSED",
"projectDomain": "social.io" "projectDomain": "social.io"
},
"release": {
"registries": [
"https://verdaccio.lossless.digital"
],
"accessLevel": "public"
} }
}, },
"npmci": { "@ship.zone/szci": {
"npmRegistryUrl": "verdaccio.lossless.one", "npmRegistryUrl": "verdaccio.lossless.one",
"npmGlobalTools": [], "npmGlobalTools": []
"npmAccessLevel": "private"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@social.io/catalog", "name": "@social.io/catalog",
"version": "1.3.0", "version": "1.4.0",
"private": false, "private": false,
"description": "catalog for social.io", "description": "catalog for social.io",
"main": "dist_ts_web/index.js", "main": "dist_ts_web/index.js",
@@ -17,23 +17,23 @@
"dependencies": { "dependencies": {
"@design.estate/dees-domtools": "^2.3.6", "@design.estate/dees-domtools": "^2.3.6",
"@design.estate/dees-element": "^2.1.3", "@design.estate/dees-element": "^2.1.3",
"@design.estate/dees-wcctools": "^1.2.1", "@design.estate/dees-wcctools": "^2.0.1",
"@losslessone_private/loint-pubapi": "^1.0.14", "@losslessone_private/loint-pubapi": "^1.0.14",
"@social.io/interfaces": "^1.2.1", "@social.io/interfaces": "^1.2.1",
"lucide": "^0.556.0", "lucide": "^0.561.0",
"rrweb": "2.0.0-alpha.4", "rrweb": "2.0.0-alpha.4",
"rrweb-player": "1.0.0-alpha.4", "rrweb-player": "1.0.0-alpha.4",
"rrweb-snapshot": "2.0.0-alpha.4" "rrweb-snapshot": "2.0.0-alpha.4"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^3.1.2", "@git.zone/tsbuild": "^4.0.2",
"@git.zone/tsbundle": "^2.6.3", "@git.zone/tsbundle": "^2.6.3",
"@git.zone/tsrun": "^2.0.0", "@git.zone/tsrun": "^2.0.1",
"@git.zone/tstest": "^3.1.3", "@git.zone/tstest": "^3.1.3",
"@git.zone/tswatch": "^2.3.5", "@git.zone/tswatch": "^2.3.13",
"@push.rocks/projectinfo": "^5.0.2", "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/smartenv": "^6.0.0", "@push.rocks/smartenv": "^6.0.0",
"@types/node": "^24.10.1" "@types/node": "^25.0.3"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

906
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@social.io/catalog', name: '@social.io/catalog',
version: '1.3.0', version: '1.4.0',
description: 'catalog for social.io' description: 'catalog for social.io'
} }

View File

@@ -4,35 +4,35 @@ export const colors = {
// Background colors - softer, more subtle // Background colors - softer, more subtle
background: { background: {
light: 'hsl(0 0% 100%)', light: 'hsl(0 0% 100%)',
dark: 'hsl(224 71.4% 4.1%)' dark: 'hsl(0 0% 4%)'
}, },
// Foreground colors - less contrast for modern look // Foreground colors - less contrast for modern look
foreground: { foreground: {
light: 'hsl(224 71.4% 4.1%)', light: 'hsl(0 0% 4%)',
dark: 'hsl(210 20% 98%)' dark: 'hsl(0 0% 98%)'
}, },
// Card colors - subtle elevation // Card colors - subtle elevation
card: { card: {
light: 'hsl(0 0% 100%)', light: 'hsl(0 0% 100%)',
dark: 'hsl(224 71.4% 4.1%)' dark: 'hsl(0 0% 4%)'
}, },
cardForeground: { cardForeground: {
light: 'hsl(224 71.4% 4.1%)', light: 'hsl(0 0% 4%)',
dark: 'hsl(210 20% 98%)' dark: 'hsl(0 0% 98%)'
}, },
// Popover colors // Popover colors
popover: { popover: {
light: 'hsl(0 0% 100%)', light: 'hsl(0 0% 100%)',
dark: 'hsl(222.2 84% 4.9%)' dark: 'hsl(0 0% 5%)'
}, },
popoverForeground: { popoverForeground: {
light: 'hsl(222.2 84% 4.9%)', light: 'hsl(0 0% 5%)',
dark: 'hsl(210 40% 98%)' dark: 'hsl(0 0% 98%)'
}, },
// Primary colors - modern indigo/blue // Primary colors - modern indigo/blue
@@ -42,41 +42,41 @@ export const colors = {
}, },
primaryForeground: { primaryForeground: {
light: 'hsl(210 20% 98%)', light: 'hsl(0 0% 98%)',
dark: 'hsl(224 71.4% 4.1%)' dark: 'hsl(0 0% 4%)'
}, },
// Secondary colors - more subtle // Secondary colors - more subtle
secondary: { secondary: {
light: 'hsl(220 14.3% 95.9%)', light: 'hsl(0 0% 96%)',
dark: 'hsl(215 27.9% 16.9%)' dark: 'hsl(0 0% 17%)'
}, },
secondaryForeground: { secondaryForeground: {
light: 'hsl(220.9 39.3% 11%)', light: 'hsl(0 0% 11%)',
dark: 'hsl(210 20% 98%)' dark: 'hsl(0 0% 98%)'
}, },
// Muted colors - softer grays // Muted colors - softer grays
muted: { muted: {
light: 'hsl(220 14.3% 95.9%)', light: 'hsl(0 0% 96%)',
dark: 'hsl(215 27.9% 16.9%)' dark: 'hsl(0 0% 17%)'
}, },
mutedForeground: { mutedForeground: {
light: 'hsl(220 8.9% 46.1%)', light: 'hsl(0 0% 46%)',
dark: 'hsl(217.9 10.6% 64.9%)' dark: 'hsl(0 0% 65%)'
}, },
// Accent colors - subtle hover states // Accent colors - subtle hover states
accent: { accent: {
light: 'hsl(220 14.3% 95.9%)', light: 'hsl(0 0% 96%)',
dark: 'hsl(215 27.9% 16.9%)' dark: 'hsl(0 0% 17%)'
}, },
accentForeground: { accentForeground: {
light: 'hsl(220.9 39.3% 11%)', light: 'hsl(0 0% 11%)',
dark: 'hsl(210 20% 98%)' dark: 'hsl(0 0% 98%)'
}, },
// Destructive colors - softer red // Destructive colors - softer red
@@ -92,14 +92,14 @@ export const colors = {
// Border color - very subtle // Border color - very subtle
border: { border: {
light: 'hsl(220 13% 91%)', light: 'hsl(0 0% 91%)',
dark: 'hsl(215 27.9% 16.9%)' dark: 'hsl(0 0% 17%)'
}, },
// Input color // Input color
input: { input: {
light: 'hsl(214.3 31.8% 91.4%)', light: 'hsl(0 0% 91%)',
dark: 'hsl(217.2 32.6% 17.5%)' dark: 'hsl(0 0% 18%)'
}, },
// Ring color - subtle focus indicator // Ring color - subtle focus indicator

View File

@@ -185,7 +185,7 @@ export const focusRing = css`
outline: 2px solid transparent; outline: 2px solid transparent;
outline-offset: 2px; outline-offset: 2px;
&:focus-visible { &:focus-visible {
outline-color: ${cssManager.bdTheme('hsl(222.2 84% 4.9%)', 'hsl(212.7 26.8% 83.9%)')}; outline-color: ${cssManager.bdTheme('hsl(0 0% 5%)', 'hsl(0 0% 84%)')};
} }
`; `;

View File

@@ -6,12 +6,13 @@ import {
type TemplateResult, type TemplateResult,
cssManager, cssManager,
css, css,
unsafeCSS,
state,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
import { SioCombox } from './sio-combox.js'; import { SioCombox } from './sio-combox.js';
import { SioIcon } from './sio-icon.js'; import { SioIcon } from './sio-icon.js';
import { state } from '@design.estate/dees-element';
SioCombox; SioCombox;
SioIcon; SioIcon;
@@ -44,194 +45,214 @@ export class SioFab extends DeesElement {
domtools.DomTools.setupDomTools(); domtools.DomTools.setupDomTools();
} }
public static styles = [
cssManager.defaultStyles,
css`
:host {
will-change: transform;
position: absolute;
display: block;
bottom: 20px;
right: 20px;
z-index: 10000;
color: #fff;
--fab-gradient-start: #6366f1;
--fab-gradient-mid: #8b5cf6;
--fab-gradient-end: #a855f7;
--fab-gradient-hover-end: #c026d3;
--fab-shadow-color: rgba(139, 92, 246, 0.25);
--fab-size: 60px;
--fab-combox-offset: calc(var(--fab-size) + ${unsafeCSS(spacing["4"])});
}
#mainbox {
transition: ${unsafeCSS(transitions.all)};
position: absolute;
bottom: 0px;
right: 0px;
height: var(--fab-size);
width: var(--fab-size);
box-shadow: 0 4px 16px -2px rgba(0, 0, 0, 0.1), 0 2px 8px -2px rgba(0, 0, 0, 0.06);
line-height: var(--fab-size);
text-align: center;
cursor: pointer;
background: linear-gradient(135deg, var(--fab-gradient-start) 0%, var(--fab-gradient-mid) 50%, var(--fab-gradient-end) 100%);
color: white;
border-radius: ${unsafeCSS(radius.full)};
user-select: none;
border: none;
animation: fabEntrance 300ms cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
#mainbox::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 50%);
opacity: 0;
transition: opacity 200ms ease;
}
#mainbox::after {
content: '';
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
background: linear-gradient(135deg, var(--fab-gradient-start), var(--fab-gradient-end));
border-radius: inherit;
z-index: -1;
opacity: 0;
filter: blur(12px);
transition: opacity 300ms ease;
}
#mainbox:hover::before {
opacity: 1;
}
#mainbox:hover::after {
opacity: 0.3;
}
@keyframes fabEntrance {
from {
transform: scale(0.8);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
#mainbox:hover {
transform: scale(1.02);
background: linear-gradient(135deg, var(--fab-gradient-start) 0%, var(--fab-gradient-mid) 50%, var(--fab-gradient-hover-end) 100%);
box-shadow: 0 8px 20px -4px var(--fab-shadow-color);
}
#mainbox:active {
transform: scale(0.98);
box-shadow: 0 4px 12px -2px var(--fab-shadow-color);
}
#mainbox.pulse::after {
animation: fabPulse 0.6s ease-out forwards;
}
@keyframes fabPulse {
0% {
box-shadow: 0 0 0 0 rgba(139, 92, 246, 0.4);
opacity: 1;
}
100% {
box-shadow: 0 0 0 12px rgba(139, 92, 246, 0);
opacity: 0;
}
}
#mainbox .icon {
position: absolute;
top: 0px;
left: 0px;
will-change: transform, opacity;
transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#mainbox .icon.open {
opacity: 1;
transform: rotate(0deg) scale(1);
}
#mainbox .icon.close {
opacity: 0;
transform: rotate(-45deg) scale(0.9);
}
/* When combox is open */
:host(.combox-open) #mainbox .icon.open {
opacity: 0;
transform: rotate(45deg) scale(0.9);
}
:host(.combox-open) #mainbox .icon.close {
opacity: 1;
transform: rotate(0deg) scale(1);
}
#mainbox .icon sio-icon {
color: white;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
}
#mainbox .icon.close sio-icon {
transform: scale(1);
}
#comboxContainer {
position: absolute;
bottom: 0;
right: 0;
pointer-events: none;
}
#comboxContainer sio-combox {
position: absolute;
bottom: var(--fab-combox-offset);
right: 0;
transition: ${unsafeCSS(transitions.all)};
will-change: transform;
transform: translateY(${unsafeCSS(spacing["5"])});
opacity: 0;
pointer-events: none;
}
#comboxContainer.show {
pointer-events: all;
}
#comboxContainer.show sio-combox {
transform: translateY(0px);
opacity: 1;
pointer-events: all;
}
`,
// Mobile responsive styles - smaller FAB on phablet and phone
cssManager.cssForPhablet(css`
:host {
--fab-size: 48px;
--fab-combox-offset: calc(var(--fab-size) + ${unsafeCSS(spacing["3"])});
bottom: 16px;
right: 16px;
}
`),
];
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`
${domtools.elementBasic.styles}
<style>
:host {
will-change: transform;
position: absolute;
display: block;
bottom: 20px;
right: 20px;
z-index: 10000;
color: #fff;
--fab-gradient-start: #6366f1;
--fab-gradient-mid: #8b5cf6;
--fab-gradient-end: #a855f7;
--fab-gradient-hover-end: #c026d3;
--fab-shadow-color: rgba(139, 92, 246, 0.25);
}
#mainbox {
transition: ${transitions.all};
position: absolute;
bottom: 0px;
right: 0px;
height: 60px;
width: 60px;
box-shadow: 0 4px 16px -2px rgba(0, 0, 0, 0.1), 0 2px 8px -2px rgba(0, 0, 0, 0.06);
line-height: 60px;
text-align: center;
cursor: pointer;
background: linear-gradient(135deg, var(--fab-gradient-start) 0%, var(--fab-gradient-mid) 50%, var(--fab-gradient-end) 100%);
color: white;
border-radius: ${radius.full};
user-select: none;
border: none;
animation: fabEntrance 300ms cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
position: relative;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
#mainbox::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.2) 0%, rgba(255, 255, 255, 0) 50%);
opacity: 0;
transition: opacity 200ms ease;
}
#mainbox::after {
content: '';
position: absolute;
top: -4px;
left: -4px;
right: -4px;
bottom: -4px;
background: linear-gradient(135deg, var(--fab-gradient-start), var(--fab-gradient-end));
border-radius: inherit;
z-index: -1;
opacity: 0;
filter: blur(12px);
transition: opacity 300ms ease;
}
#mainbox:hover::before {
opacity: 1;
}
#mainbox:hover::after {
opacity: 0.3;
}
@keyframes fabEntrance {
from {
transform: scale(0.8);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
#mainbox:hover {
transform: scale(1.02);
background: linear-gradient(135deg, var(--fab-gradient-start) 0%, var(--fab-gradient-mid) 50%, var(--fab-gradient-hover-end) 100%);
}
#mainbox:hover {
box-shadow: 0 8px 20px -4px var(--fab-shadow-color);
}
#mainbox:active {
transform: scale(0.98);
box-shadow: 0 4px 12px -2px var(--fab-shadow-color);
}
#mainbox.pulse::after {
animation: fabPulse 0.6s ease-out forwards;
}
@keyframes fabPulse {
0% {
box-shadow: 0 0 0 0 rgba(139, 92, 246, 0.4);
opacity: 1;
}
100% {
box-shadow: 0 0 0 12px rgba(139, 92, 246, 0);
opacity: 0;
}
}
#mainbox .icon {
position: absolute;
top: 0px;
left: 0px;
will-change: transform, opacity;
transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1);
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#mainbox .icon.open {
opacity: ${this.showCombox ? '0' : '1'};
transform: ${this.showCombox ? 'rotate(45deg) scale(0.9)' : 'rotate(0deg) scale(1)'};
}
#mainbox .icon.close {
opacity: ${this.showCombox ? '1' : '0'};
transform: ${this.showCombox ? 'rotate(0deg) scale(1)' : 'rotate(-45deg) scale(0.9)'};
}
#mainbox .icon sio-icon {
color: white;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
}
#mainbox .icon.close sio-icon {
transform: scale(1);
}
#comboxContainer {
position: absolute;
bottom: 0;
right: 0;
pointer-events: none;
}
#comboxContainer sio-combox {
position: absolute;
bottom: calc(60px + ${spacing["4"]});
right: 0;
transition: ${transitions.all};
will-change: transform;
transform: translateY(${spacing["5"]});
opacity: 0;
pointer-events: none;
}
#comboxContainer.show {
pointer-events: all;
}
#comboxContainer.show sio-combox {
transform: translateY(0px);
opacity: 1;
pointer-events: all;
}
</style>
<div id="mainbox" <div id="mainbox"
class="${this.shouldPulse ? 'pulse' : ''}" class="${this.shouldPulse ? 'pulse' : ''}"
@click=${this.toggleCombox} @click=${this.toggleCombox}
@animationend=${() => { this.shouldPulse = false; }} @animationend=${() => { this.shouldPulse = false; }}
> >
<div class="icon open"> <div class="icon open">
<sio-icon icon="message-square" size="28"></sio-icon> <sio-icon icon="message-square" size="24"></sio-icon>
</div> </div>
<div class="icon close"> <div class="icon close">
<sio-icon icon="x" size="22"></sio-icon> <sio-icon icon="x" size="20"></sio-icon>
</div> </div>
</div> </div>
<div id="comboxContainer" class="${this.showCombox ? 'show' : ''}"> <div id="comboxContainer" class="${this.showCombox ? 'show' : ''}">
@@ -272,6 +293,15 @@ export class SioFab extends DeesElement {
public async updated(changedProperties: Map<string | number | symbol, unknown>) { public async updated(changedProperties: Map<string | number | symbol, unknown>) {
super.updated(changedProperties); super.updated(changedProperties);
// Update host class based on combox state
if (changedProperties.has('showCombox')) {
if (this.showCombox) {
this.classList.add('combox-open');
} else {
this.classList.remove('combox-open');
}
}
// Set reference object when combox is rendered // Set reference object when combox is rendered
if ((changedProperties.has('showCombox') || changedProperties.has('hasShownOnce')) && if ((changedProperties.has('showCombox') || changedProperties.has('hasShownOnce')) &&
(this.showCombox || this.hasShownOnce)) { (this.showCombox || this.hasShownOnce)) {