feat: video letterboxing, card badge styling, component updates
- Add object-fit: contain + black background for video in DTMediaFrame - Style .dt-card-badge with mode-colored background, padding, and bevel-aware positioning (negative right offset for clean diagonal clip) - Restore DTStaggerContainer in react-native (was incorrectly deleted) - Update DTGallery, DTModal, DTMobileFilterOverlay, DTMediaFrame components - Refresh showcase pages for desktop and mobile Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { DTCard, DTStaggerContainer } from '@dangerousthings/react';
|
||||
import { DTCard } from '@dangerousthings/react';
|
||||
import { Section, Row, CodeLabel } from '../components/Section';
|
||||
|
||||
function AnimBox({ className, label }: { className: string; label: string }) {
|
||||
@@ -66,7 +66,7 @@ function ProgressBarDemo() {
|
||||
<DTCard
|
||||
key={v}
|
||||
variant={v}
|
||||
title={`${v.toUpperCase()} ${progress[i]}%`}
|
||||
title={`${v} ${progress[i]}%`}
|
||||
progress={progress[i]}
|
||||
style={{ width: 160, transition: 'all 0.1s ease-out' }}
|
||||
>
|
||||
@@ -90,13 +90,12 @@ function ProgressBarDemo() {
|
||||
|
||||
export function AnimationsPage() {
|
||||
const [entranceKey, setEntranceKey] = useState(0);
|
||||
const [staggerKey, setStaggerKey] = useState(0);
|
||||
const [accordionExpanded, setAccordionExpanded] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 className="page-title">Animations</h1>
|
||||
<p className="page-subtitle">Entrance animations, interactive effects, stagger containers, and transition utilities.</p>
|
||||
<p className="page-subtitle">Entrance animations, interactive effects, and transition utilities.</p>
|
||||
|
||||
<Section title="Entrance Animations" description="One-shot animations for elements entering the viewport.">
|
||||
<Row key={entranceKey}>
|
||||
@@ -119,28 +118,6 @@ export function AnimationsPage() {
|
||||
<CodeLabel text=".dt-animate-pulse | .dt-animate-ping | .dt-animate-spin" />
|
||||
</Section>
|
||||
|
||||
<Section title="Stagger Container" description="Automatic staggered scale-in animation for child elements. Customizable via --dt-stagger-duration and --dt-stagger-interval.">
|
||||
<DTStaggerContainer
|
||||
key={staggerKey}
|
||||
className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-6 gap-dt-3"
|
||||
>
|
||||
{Array.from({ length: 12 }, (_, i) => (
|
||||
<DTCard key={i} title={`CARD ${i + 1}`} style={{ textAlign: 'center' }}>
|
||||
<div className="card-body" style={{ fontSize: '0.75rem' }}>Item #{i + 1}</div>
|
||||
</DTCard>
|
||||
))}
|
||||
</DTStaggerContainer>
|
||||
<button
|
||||
className="btn-secondary"
|
||||
style={{ marginTop: 'var(--space-4)' }}
|
||||
onClick={() => setStaggerKey(k => k + 1)}
|
||||
type="button"
|
||||
>
|
||||
REPLAY STAGGER
|
||||
</button>
|
||||
<CodeLabel text="<DTStaggerContainer> — nth-child delays up to 24 children" />
|
||||
</Section>
|
||||
|
||||
<Section title="Transition Utilities" description="Accordion expand, chevron rotation, and progress bar transitions.">
|
||||
<div style={{ maxWidth: 400 }}>
|
||||
<button
|
||||
@@ -156,7 +133,6 @@ export function AnimationsPage() {
|
||||
cursor: 'pointer',
|
||||
color: 'var(--color-text)',
|
||||
fontWeight: 600,
|
||||
textTransform: 'uppercase',
|
||||
}}
|
||||
aria-expanded={accordionExpanded}
|
||||
onClick={() => setAccordionExpanded(!accordionExpanded)}
|
||||
|
||||
@@ -53,12 +53,12 @@ export function BevelsPage() {
|
||||
<Row>
|
||||
{modes.map(mode => (
|
||||
<button key={mode} className={`dt-menu-item mode-${mode}`} type="button" onClick={() => setModalVariant(mode)}>
|
||||
{mode.toUpperCase()} MODAL
|
||||
{mode} Modal
|
||||
</button>
|
||||
))}
|
||||
</Row>
|
||||
<CodeLabel text="<DTModal variant='normal' visible onDismiss title='...'>content</DTModal>" />
|
||||
<DTModal visible={modalVariant !== null} onDismiss={() => setModalVariant(null)} variant={modalVariant ?? 'normal'} title={`${(modalVariant ?? 'normal').toUpperCase()} MODAL`}>
|
||||
<DTModal visible={modalVariant !== null} onDismiss={() => setModalVariant(null)} variant={modalVariant ?? 'normal'} title={`${modalVariant ?? 'normal'} Modal`}>
|
||||
<p style={{ marginBottom: 'var(--space-4)' }}>This is a <strong>{modalVariant}</strong> modal with beveled card shape, backdrop blur, and scale-in animation.</p>
|
||||
<p style={{ color: 'var(--color-text-muted)', fontSize: '0.85rem' }}>Click the backdrop or press Escape to dismiss.</p>
|
||||
</DTModal>
|
||||
@@ -74,7 +74,7 @@ export function BevelsPage() {
|
||||
</button>
|
||||
</Row>
|
||||
<CodeLabel text="<DTDrawer position='right' heading='...' visible onDismiss>content</DTDrawer>" />
|
||||
<DTDrawer visible={drawerSide !== null} onDismiss={() => setDrawerSide(null)} position={drawerSide ?? 'right'} heading={`${(drawerSide ?? 'right').toUpperCase()} DRAWER`} headingVariant={drawerSide === 'left' ? 'other' : 'emphasis'}>
|
||||
<DTDrawer visible={drawerSide !== null} onDismiss={() => setDrawerSide(null)} position={drawerSide ?? 'right'} heading={`${drawerSide ?? 'right'} Drawer`} headingVariant={drawerSide === 'left' ? 'other' : 'emphasis'}>
|
||||
<p style={{ marginBottom: 'var(--space-4)' }}>Sliding panel from the <strong>{drawerSide}</strong> edge with beveled corners and backdrop blur.</p>
|
||||
<p style={{ color: 'var(--color-text-muted)', fontSize: '0.85rem' }}>Click the backdrop, press Escape, or click ✕ to dismiss.</p>
|
||||
</DTDrawer>
|
||||
@@ -91,7 +91,7 @@ export function BevelsPage() {
|
||||
|
||||
<Section title="Accent Top" description="Used on accordion headers and menu items.">
|
||||
<div className="dt-accent-top" style={{ padding: 'var(--space-4)', background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}>
|
||||
<span style={{ fontWeight: 600, textTransform: 'uppercase' }}>Thick Top Border Accent</span>
|
||||
<span style={{ fontWeight: 600 }}>Thick Top Border Accent</span>
|
||||
</div>
|
||||
<CodeLabel text=".dt-accent-top" />
|
||||
</Section>
|
||||
@@ -99,7 +99,7 @@ export function BevelsPage() {
|
||||
<Section title="Card Color Modes" description="Per-card mode coloring — see Advanced Cards page for full demos.">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-dt-3">
|
||||
{modes.map(mode => (
|
||||
<DTCard key={mode} variant={mode} title={mode.toUpperCase()}>
|
||||
<DTCard key={mode} variant={mode} title={mode}>
|
||||
<div className="card-body" style={{ fontSize: '0.75rem' }}>mode-{mode}</div>
|
||||
</DTCard>
|
||||
))}
|
||||
|
||||
@@ -58,7 +58,7 @@ export function HexBackgroundPage({ hexProps, onHexPropsChange }: HexBackgroundP
|
||||
{sliders.map(({ key, label, min, max, step }) => (
|
||||
<div key={key} style={{ display: 'grid', gridTemplateColumns: '1fr auto', alignItems: 'center', gap: 'var(--space-4)' }}>
|
||||
<label style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted)', textTransform: 'uppercase', letterSpacing: '0.1em' }}>
|
||||
<span style={{ fontSize: '0.8rem', color: 'var(--color-text-muted)', letterSpacing: '0.1em' }}>
|
||||
{label}
|
||||
</span>
|
||||
<input
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { DTCard, DTStaggerContainer } from '@dangerousthings/react';
|
||||
import { DTCard } from '@dangerousthings/react';
|
||||
import type { DTVariant } from '@dangerousthings/tokens';
|
||||
import { Section, CodeLabel } from '../components/Section';
|
||||
|
||||
const categories: { hash: string; title: string; desc: string; mode: DTVariant; count: number }[] = [
|
||||
{ hash: 'bevels', title: 'Bevels', desc: 'Angular clip-path patterns — cards, buttons, badges, media frames, modals, drawers', mode: 'normal', count: 8 },
|
||||
{ hash: 'forms', title: 'Forms', desc: 'Text inputs, checkboxes, switches, radios, progress bars, accordions, steppers', mode: 'success', count: 7 },
|
||||
{ hash: 'animations', title: 'Animations', desc: 'Entrance animations, stagger containers, transition utilities, scrollbar styling', mode: 'other', count: 5 },
|
||||
{ hash: 'animations', title: 'Animations', desc: 'Entrance animations, transition utilities, scrollbar styling', mode: 'other', count: 5 },
|
||||
{ hash: 'cards-advanced', title: 'Advanced Cards', desc: 'Card color modes, progress bars, badge overlays, interactive bevel buttons, feature legend', mode: 'warning', count: 6 },
|
||||
{ hash: 'tokens', title: 'Tokens', desc: 'Color palette, typography, spacing, and shape values for the active brand', mode: 'normal', count: 3 },
|
||||
];
|
||||
@@ -31,7 +31,6 @@ export function HomePage() {
|
||||
fontWeight: 900,
|
||||
letterSpacing: '0.15em',
|
||||
marginBottom: '0.25rem',
|
||||
textTransform: 'uppercase',
|
||||
}}>
|
||||
DANGEROUS THINGS
|
||||
</h1>
|
||||
@@ -40,7 +39,6 @@ export function HomePage() {
|
||||
fontSize: '1.25rem',
|
||||
fontWeight: 700,
|
||||
letterSpacing: '0.2em',
|
||||
textTransform: 'uppercase',
|
||||
marginTop: 0,
|
||||
}}>
|
||||
DESIGN SYSTEM
|
||||
@@ -71,16 +69,15 @@ export function HomePage() {
|
||||
color: 'var(--color-text-muted)',
|
||||
fontSize: '0.7rem',
|
||||
letterSpacing: '0.15em',
|
||||
textTransform: 'uppercase',
|
||||
marginBottom: 'var(--space-4)',
|
||||
}}>
|
||||
COMPONENT CATALOG
|
||||
</p>
|
||||
|
||||
<DTStaggerContainer className="grid grid-cols-1 md:grid-cols-2 gap-dt-4">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-dt-4">
|
||||
{categories.map(cat => (
|
||||
<a key={cat.hash} href={`#/${cat.hash}`} style={{ textDecoration: 'none', color: 'inherit' }}>
|
||||
<DTCard variant={cat.mode} title={cat.title.toUpperCase()}>
|
||||
<DTCard variant={cat.mode} title={cat.title}>
|
||||
<div className="card-body">{cat.desc}</div>
|
||||
{cat.count > 0 && (
|
||||
<div style={{ color: 'var(--color-text-muted)', fontSize: '0.7rem', marginTop: 'var(--space-2)' }}>
|
||||
@@ -90,7 +87,7 @@ export function HomePage() {
|
||||
</DTCard>
|
||||
</a>
|
||||
))}
|
||||
</DTStaggerContainer>
|
||||
</div>
|
||||
|
||||
<Section title="Quick Start" description="Import the React components and CSS to get started.">
|
||||
<div className="terminal dt-accent-top">
|
||||
|
||||
@@ -43,7 +43,6 @@ body {
|
||||
font-size: 0.875rem;
|
||||
letter-spacing: 0.1em;
|
||||
color: var(--color-primary);
|
||||
text-transform: uppercase;
|
||||
padding-bottom: var(--space-4);
|
||||
border-bottom: 2px solid var(--color-primary);
|
||||
}
|
||||
@@ -65,7 +64,6 @@ body {
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.05em;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
|
||||
@@ -93,7 +91,6 @@ body {
|
||||
font-size: 0.625rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-transform: uppercase;
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
|
||||
@@ -117,7 +114,6 @@ body {
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
letter-spacing: 0.02em;
|
||||
text-transform: uppercase;
|
||||
border-left: 3px solid transparent;
|
||||
transition: all var(--transition-fast);
|
||||
}
|
||||
@@ -151,7 +147,6 @@ body {
|
||||
font-weight: 700;
|
||||
font-size: 1.125rem;
|
||||
color: var(--color-primary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: var(--space-2);
|
||||
padding-bottom: var(--space-2);
|
||||
@@ -175,7 +170,6 @@ body {
|
||||
.demo-label {
|
||||
color: var(--color-text-muted);
|
||||
font-size: 0.6875rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
margin-bottom: var(--space-2);
|
||||
margin-top: var(--space-4);
|
||||
@@ -200,7 +194,6 @@ body {
|
||||
padding: var(--space-3) var(--space-6);
|
||||
font-weight: 700;
|
||||
font-size: 0.875rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
cursor: pointer;
|
||||
transition: all var(--transition-fast);
|
||||
@@ -244,7 +237,6 @@ body {
|
||||
.card-title {
|
||||
font-weight: 900;
|
||||
font-size: 1rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
@@ -260,7 +252,6 @@ body {
|
||||
padding: var(--space-2) var(--space-3);
|
||||
font-weight: 600;
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
@@ -300,7 +291,6 @@ input:focus {
|
||||
font-weight: 900;
|
||||
font-size: 1.75rem;
|
||||
color: var(--color-primary);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
margin-bottom: var(--space-2);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import { Text } from 'react-native-paper';
|
||||
import {
|
||||
DTCard,
|
||||
DTLabel,
|
||||
DTStaggerContainer,
|
||||
useDTTheme,
|
||||
useScaleIn,
|
||||
usePulse,
|
||||
} from '@dangerousthings/react-native';
|
||||
import type { DTVariant } from '@dangerousthings/react-native';
|
||||
import { ScreenContainer } from '../components/ScreenContainer';
|
||||
import { DemoSection } from '../components/DemoSection';
|
||||
import { CodeLabel } from '../components/CodeLabel';
|
||||
@@ -20,44 +17,8 @@ export function AnimationsScreen() {
|
||||
const scaleAnim = useScaleIn({ duration: 600 });
|
||||
const pulseAnim = usePulse(true);
|
||||
|
||||
const modes: DTVariant[] = ['normal', 'emphasis', 'warning', 'success', 'other'];
|
||||
|
||||
return (
|
||||
<ScreenContainer>
|
||||
{/* Stagger Container */}
|
||||
<DemoSection
|
||||
title="DTStaggerContainer"
|
||||
variant="normal"
|
||||
description="Staggered scale-in entrance animation for child elements."
|
||||
>
|
||||
<DTStaggerContainer duration={330} interval={75}>
|
||||
{modes.map((mode) => (
|
||||
<DTCard key={mode} mode={mode} title={mode.toUpperCase()} style={{ marginBottom: 12 }}>
|
||||
<Text variant="bodySmall" style={{ color: theme.colors.onSurface }}>
|
||||
Staggered entrance with scale animation
|
||||
</Text>
|
||||
</DTCard>
|
||||
))}
|
||||
</DTStaggerContainer>
|
||||
<CodeLabel text="<DTStaggerContainer duration={330} interval={75}>" />
|
||||
</DemoSection>
|
||||
|
||||
{/* Stagger with Labels */}
|
||||
<DemoSection
|
||||
title="Staggered Labels"
|
||||
variant="emphasis"
|
||||
description="Labels with staggered entrance animation."
|
||||
>
|
||||
<DTStaggerContainer duration={400} interval={100}>
|
||||
{modes.map((mode) => (
|
||||
<View key={mode} style={{ marginBottom: 8 }}>
|
||||
<DTLabel primaryText={mode.toUpperCase()} mode={mode} />
|
||||
</View>
|
||||
))}
|
||||
</DTStaggerContainer>
|
||||
<CodeLabel text="DTStaggerContainer > DTLabel — customizable timing" />
|
||||
</DemoSection>
|
||||
|
||||
{/* Scale-In Hook */}
|
||||
<DemoSection
|
||||
title="useScaleIn"
|
||||
|
||||
@@ -5,7 +5,6 @@ import {
|
||||
DTCard,
|
||||
DTChip,
|
||||
DTBadgeOverlay,
|
||||
DTStaggerContainer,
|
||||
useDTTheme,
|
||||
} from '@dangerousthings/react-native';
|
||||
import type { DTVariant } from '@dangerousthings/react-native';
|
||||
@@ -83,29 +82,6 @@ export function CardsAdvancedScreen() {
|
||||
<CodeLabel text="<DTBadgeOverlay position='bottom-right'><DTChip variant='warning'>LAB</DTChip>" />
|
||||
</DemoSection>
|
||||
|
||||
{/* Stagger + Progress */}
|
||||
<DemoSection
|
||||
title="Staggered Cards with Progress"
|
||||
variant="success"
|
||||
description="Stagger container with progress bars across all modes."
|
||||
>
|
||||
<DTStaggerContainer>
|
||||
{modes.map((mode) => (
|
||||
<DTCard
|
||||
key={mode}
|
||||
mode={mode}
|
||||
title={mode.toUpperCase()}
|
||||
progress={Math.random()}
|
||||
style={{ marginBottom: 12 }}
|
||||
>
|
||||
<Text variant="bodySmall" style={{ color: theme.colors.onSurface }}>
|
||||
Staggered + progress
|
||||
</Text>
|
||||
</DTCard>
|
||||
))}
|
||||
</DTStaggerContainer>
|
||||
<CodeLabel text="DTStaggerContainer > DTCard progress" />
|
||||
</DemoSection>
|
||||
</ScreenContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -58,14 +58,14 @@ const categories: {
|
||||
},
|
||||
{
|
||||
title: 'ADVANCED CARDS',
|
||||
subtitle: 'Selected state, progress bar, badge overlays, stagger',
|
||||
subtitle: 'Selected state, progress bar, badge overlays',
|
||||
mode: 'emphasis',
|
||||
route: 'CardsAdvanced',
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
title: 'ANIMATIONS',
|
||||
subtitle: 'DTStaggerContainer, useScaleIn, usePulse',
|
||||
subtitle: 'useScaleIn, usePulse',
|
||||
mode: 'success',
|
||||
route: 'Animations',
|
||||
count: 3,
|
||||
|
||||
Reference in New Issue
Block a user