// Use theme variables with namespace to avoid conflicts
@use 'variables' as vars;
@use 'mixins' as mix;
// ============================================
// Hikari // Hikari // Hikari // Hikari // Hikari Tree View Component - Styling Component Component Component Component
// ============================================
// Base Tree Styles
// ============================================
.hi-tree {
// Layout
display: flex;
flex-direction: column;
width: 100%;
max-width: 100%;
// Appearance
background: transparent;
border: none;
border-radius: 0;
// Padding
padding: 0;
// Shadow
box-shadow: none;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-normal vars.$hikari-ease-smooth;
// Hide native scrollbar (using custom scrollbar component)
@include mix.scrollbar-hidden;
// Card variant (when used as a standalone card)
&.hi-tree-card {
background: rgba(255, 255, 255, 0.9);
border: 1px solid var(--hi-color-border);
border-radius: vars.$hikari-radius-fui-md;
padding: 0.5rem;
box-shadow:
0 4px 8px rgba(214, 236, 240, 0.5),
0 0 0 1px var(--hi-white-5, rgba(255, 255, 255, 0.05)) inset;
}
}
// ============================================
// Tree List
// ============================================
.hi-tree-list {
// Layout
list-style: none;
margin: 0;
padding: 0;
// Display
display: flex;
flex-direction: column;
gap: 0.125rem;
}
// ============================================
// Tree Node
// ============================================
.hi-tree-node {
// Layout
position: relative;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-fast vars.$hikari-ease-smooth;
// Node connector (vertical line with glow)
&::before {
content: '';
position: absolute;
left: 0.75rem;
top: 0;
bottom: 0;
width: 1px;
background: linear-gradient(
180deg,
transparent,
var(--hi-primary) 20%,
var(--hi-primary) 80%,
transparent
);
--hi-glow-transparent: false;
--hi-glow-bg-color: var(--hi-color-surface);
box-shadow: 0 0 4px var(--hi-glow-color);
pointer-events: none;
}
// Last node connector adjustment
&:last-child::before {
background: linear-gradient(
180deg,
transparent,
var(--hi-primary) 20%,
var(--hi-primary) 50%,
transparent
);
}
}
// ============================================
// Tree Node Content
// ============================================
.hi-tree-node-content {
// Layout
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0.75rem;
margin: 0.125rem 0;
// Appearance
background: transparent;
border: 1px solid transparent;
border-radius: vars.$hikari-radius-fui-sm;
// Typography
font-family: vars.$hikari-font-family-sans;
font-size: vars.$hikari-font-size-sm;
color: var(--hi-color-text-primary);
line-height: 1.5;
// Cursor
cursor: pointer;
user-select: none;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-fast vars.$hikari-ease-smooth;
// Position
position: relative;
// Node connector (horizontal line)
&::after {
content: '';
position: absolute;
left: -0.5rem;
top: 50%;
width: 0.5rem;
height: 1px;
background: var(--hi-primary);
--hi-glow-transparent: false;
--hi-glow-bg-color: var(--hi-color-surface);
box-shadow: 0 0 4px var(--hi-glow-color);
pointer-events: none;
}
// Root node (no connector)
.hi-tree-root > .hi-tree-node > .hi-tree-node-content::after {
display: none;
}
// Hover glow effects
&:hover {
background: var(--hi-primary);
border-color: var(--hi-primary);
--hi-glow-transparent: false;
--hi-glow-bg-color: var(--hi-primary);
box-shadow:
0 0 12px var(--hi-glow-color),
inset 0 0 8px var(--hi-glow-color);
.hi-tree-node-icon {
color: var(--hi-color-primary);
filter: drop-shadow(0 0 4px var(--hi-glow-color));
}
.hi-tree-node-label {
color: var(--hi-color-text-primary);
}
}
// Selected state with glow background
&.hi-tree-node-selected {
background: var(--hi-primary);
border-color: var(--hi-primary);
box-shadow:
0 0 16px var(--hi-primary),
inset 0 0 12px var(--hi-primary);
.hi-tree-node-icon {
color: var(--hi-color-primary);
filter: drop-shadow(0 0 6px var(--hi-primary));
}
.hi-tree-node-label {
color: var(--hi-color-text-primary);
font-weight: 500;
}
}
// Active state with accent bar
&.hi-tree-node-active {
background: var(--hi-primary);
// Accent bar on the left
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 3px;
background: var(--hi-color-primary);
box-shadow:
0 0 8px var(--hi-color-primary),
2px 0 8px var(--hi-primary);
border-radius: 2px 0 0 2px;
}
}
// Focus state
&:focus-visible {
outline: none;
box-shadow:
0 0 0 2px var(--hi-primary),
0 0 16px var(--hi-primary);
}
// Disabled state
&.hi-tree-node-disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
// Drag-over state for drop targets
&.hi-tree-node-drag-over {
background: rgba(14, 184, 64, 0.15);
border-color: rgba(14, 184, 64, 0.5);
box-shadow:
0 0 16px rgba(14, 184, 64, 0.3),
inset 0 0 12px rgba(14, 184, 64, 0.1);
}
}
// ============================================
// Expand/Collapse Icon
// ============================================
.hi-tree-node-expand-icon {
// Layout
display: flex;
align-items: center;
justify-content: center;
width: 1rem;
height: 1rem;
flex-shrink: 0;
// Color
color: var(--hi-color-text-secondary);
// Cursor
cursor: pointer;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-normal vars.$hikari-ease-smooth;
// Icon
svg {
width: 100%;
height: 100%;
// DISABLED - migrated to JS animation
// transition: transform vars.$hikari-duration-normal vars.$hikari-ease-smooth;
}
// Expanded state (rotate 90deg)
.hi-tree-node-expanded > .hi-tree-node-content & {
transform: rotate(90deg);
color: var(--hi-color-primary);
filter: drop-shadow(0 0 4px var(--hi-primary));
}
// Hover effect
&:hover {
color: var(--hi-color-primary);
background: var(--hi-primary);
border-radius: 50%;
}
}
// ============================================
// Node Icon
// ============================================
.hi-tree-node-icon {
// Layout
display: flex;
align-items: center;
justify-content: center;
width: 1rem;
height: 1rem;
flex-shrink: 0;
// Color
color: var(--hi-color-text-secondary);
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-fast vars.$hikari-ease-smooth;
// Icon
svg {
width: 100%;
height: 100%;
}
// Animated icon on expand/collapse
.hi-tree-node-expanded > .hi-tree-node-content & {
// DISABLED - migrated to JS animation
// animation: tree-icon-bounce 0.4s vars.$hikari-ease-bounce;
}
}
// DISABLED - migrated to JS animation
// @keyframes tree-icon-bounce {
// 0%, 100% {
// transform: scale(1);
// }
// 50% {
// transform: scale(1.2);
// }
// }
// ============================================
// Node Label
// ============================================
.hi-tree-node-label {
// Layout
flex: 1;
// Typography
color: var(--hi-color-text-primary);
// Text ellipsis
@include mix.text-ellipsis;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-fast vars.$hikari-ease-smooth;
}
// ============================================
// Nested Indentation Levels
// ============================================
.hi-tree-node-children {
// Layout
list-style: none;
margin: 0;
padding: 0 0 0 1.5rem;
// Display
display: none;
flex-direction: column;
gap: 0.125rem;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-normal vars.$hikari-ease-smooth;
// Expanded state
.hi-tree-node-expanded > & {
display: flex;
// DISABLED - migrated to JS animation
// animation: tree-expand-children vars.$hikari-duration-normal vars.$hikari-ease-smooth;
}
}
// DISABLED - migrated to JS animation
// @keyframes tree-expand-children {
// from {
// opacity: 0;
// transform: translateX(-8px);
// }
// to {
// opacity: 1;
// transform: translateX(0);
// }
// }
// Nested level connector
.hi-tree-node-children .hi-tree-node {
&::before {
left: 0.75rem;
}
.hi-tree-node-content::after {
left: -0.5rem;
width: 0.5rem;
}
}
// ============================================
// Checkbox Support
// ============================================
.hi-tree-node-checkbox {
// Layout
display: flex;
align-items: center;
justify-content: center;
width: 1rem;
height: 1rem;
flex-shrink: 0;
// Appearance
border: 1px solid var(--hi-color-border);
border-radius: 3px;
background: var(--hi-card-bg);
// Cursor
cursor: pointer;
// Transitions
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-fast vars.$hikari-ease-smooth;
// Hover effect
&:hover {
border-color: var(--hi-primary);
--hi-glow-transparent: false;
--hi-glow-bg-color: var(--hi-color-surface);
box-shadow: 0 0 8px var(--hi-glow-color);
}
// Checked state
&.hi-tree-checkbox-checked {
background: var(--hi-color-primary);
border-color: var(--hi-color-primary);
--hi-glow-transparent: false;
--hi-glow-bg-color: var(--hi-color-primary);
box-shadow: 0 0 12px var(--hi-glow-color);
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0.375rem;
height: 0.625rem;
border: solid white;
border-width: 0 2px 2px 0;
transform: translate(-50%, -60%) rotate(45deg);
}
}
// Indeterminate state
&.hi-tree-checkbox-indeterminate {
background: var(--hi-color-primary);
border-color: var(--hi-color-primary);
--hi-glow-transparent: false;
--hi-glow-bg-color: var(--hi-color-primary);
box-shadow: 0 0 12px var(--hi-glow-color);
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 0.5rem;
height: 2px;
background: white;
transform: translate(-50%, -50%);
}
}
}
// ============================================
// Virtual Scrolling Support
// ============================================
.hi-tree-virtual {
// Layout
overflow-y: auto;
overflow-x: hidden;
max-height: 400px;
// Hide native scrollbar (using custom scrollbar component)
@include mix.scrollbar-hidden;
// Virtual placeholder
.hi-tree-virtual-placeholder {
height: 1px;
pointer-events: none;
}
}
// ============================================
// Loading Skeleton
// ============================================
.hi-tree-loading {
// Layout
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.5rem 0.75rem;
// Skeleton animation
.hi-tree-skeleton {
flex: 1;
height: 1rem;
background: linear-gradient(
90deg,
var(--hi-primary) 0%,
var(--hi-primary) 50%,
var(--hi-primary) 100%
);
background-size: 200% 100%;
border-radius: vars.$hikari-radius-fui-sm;
// DISABLED - migrated to JS animation
// animation: tree-skeleton-loading 1.5s ease-in-out infinite;
}
}
// DISABLED - migrated to JS animation
// @keyframes tree-skeleton-loading {
// 0% {
// background-position: 200% 0;
// }
// 100% {
// background-position: -200% 0;
// }
// }
// ============================================
// Empty State
// ============================================
.hi-tree-empty {
// Layout
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 3rem 2rem;
// Typography
color: var(--hi-color-text-secondary);
// Icon
.hi-tree-empty-icon {
width: 4rem;
height: 4rem;
margin-bottom: 1rem;
opacity: 0.5;
color: var(--hi-color-text-secondary);
svg {
width: 100%;
height: 100%;
}
}
// Message
.hi-tree-empty-message {
font-size: vars.$hikari-font-size-base;
margin-bottom: 0.5rem;
}
// Description
.hi-tree-empty-description {
font-size: vars.$hikari-font-size-sm;
opacity: 0.7;
}
}
// ============================================
// Size Variants
// ============================================
// Compact size
.hi-tree-compact {
padding: 0.375rem;
.hi-tree-node-content {
padding: 0.375rem 0.625rem;
font-size: 0.8125rem;
gap: 0.375rem;
}
.hi-tree-node-expand-icon,
.hi-tree-node-icon,
.hi-tree-node-checkbox {
width: 0.875rem;
height: 0.875rem;
}
.hi-tree-node-children {
padding-left: 1.25rem;
}
}
// Default size
.hi-tree-default {
padding: 0.5rem;
.hi-tree-node-content {
padding: 0.5rem 0.75rem;
font-size: vars.$hikari-font-size-sm;
gap: 0.5rem;
}
.hi-tree-node-expand-icon,
.hi-tree-node-icon,
.hi-tree-node-checkbox {
width: 1rem;
height: 1rem;
}
.hi-tree-node-children {
padding-left: 1.5rem;
}
}
// Spacious size
.hi-tree-spacious {
padding: 0.625rem;
.hi-tree-node-content {
padding: 0.75rem 1rem;
font-size: 0.9375rem;
gap: 0.625rem;
}
.hi-tree-node-expand-icon,
.hi-tree-node-icon,
.hi-tree-node-checkbox {
width: 1.125rem;
height: 1.125rem;
}
.hi-tree-node-children {
padding-left: 2rem;
}
}
// ============================================
// Animations
// ============================================
// Fade-in animation for tree nodes
.hi-tree-animate-in {
.hi-tree-node {
opacity: 0;
// DISABLED - migrated to JS animation
// animation: tree-node-fade-in vars.$hikari-duration-normal vars.$hikari-ease-smooth forwards;
@for $i from 1 through 50 {
&:nth-child(#{$i}) {
animation-delay: #{$i * 0.03s};
}
}
}
}
// DISABLED - migrated to JS animation
// @keyframes tree-node-fade-in {
// from {
// opacity: 0;
// transform: translateX(-12px);
// }
// to {
// opacity: 1;
// transform: translateX(0);
// }
// }
// Expand/collapse animation
.hi-tree-animated {
.hi-tree-node-children {
// DISABLED - migrated to JS animation
// transition: all vars.$hikari-duration-normal vars.$hikari-ease-smooth;
overflow: hidden;
&:not(.hi-tree-expanded) {
max-height: 0;
opacity: 0;
}
&.hi-tree-expanded {
max-height: 1000px;
opacity: 1;
}
}
}
// ============================================
// Drag and Drop
// ============================================
.hi-tree-draggable {
.hi-tree-node-content {
cursor: grab;
&:active {
cursor: grabbing;
}
}
// Dragging state
.hi-tree-node-dragging {
opacity: 0.5;
background: var(--hi-primary);
}
// Drop indicator
.hi-tree-drop-indicator {
height: 2px;
background: var(--hi-color-primary);
box-shadow:
0 0 8px var(--hi-color-primary),
0 0 16px var(--hi-primary);
margin: 0.25rem 0;
border-radius: 1px;
// DISABLED - migrated to JS animation
// animation: tree-drop-pulse 1s ease-in-out infinite;
}
}
// DISABLED - migrated to JS animation
// @keyframes tree-drop-pulse {
// 0%, 100% {
// opacity: 1;
// height: 2px;
// }
// 50% {
// opacity: 0.7;
// height: 3px;
// }
// }
// ============================================
// Responsive Behavior
// ============================================
@include mix.mobile {
.hi-tree {
font-size: 0.8125rem;
}
.hi-tree-node-content {
padding: 0.5rem 0.625rem;
}
.hi-tree-node-expand-icon,
.hi-tree-node-icon,
.hi-tree-node-checkbox {
width: 0.875rem;
height: 0.875rem;
}
.hi-tree-node-children {
padding-left: 1.25rem;
}
}
// ============================================
// Accessibility
// ============================================
.hi-tree-node-content:focus-visible {
outline: 2px solid var(--hi-color-primary);
outline-offset: 2px;
}
// High contrast mode
@media (prefers-contrast: high) {
.hi-tree-node-content {
border-width: 2px;
}
.hi-tree-node-content.hi-tree-node-selected {
border-width: 2px;
}
}
// Reduced motion
@media (prefers-reduced-motion: reduce) {
.hi-tree-node-content,
.hi-tree-node-expand-icon,
.hi-tree-node-icon,
.hi-tree-node-checkbox,
.hi-tree-node-children {
// DISABLED - migrated to JS animation
// transition: none;
// DISABLED - migrated to JS animation
// animation: none;
}
.hi-tree-animate-in .hi-tree-node {
// DISABLED - migrated to JS animation
// animation: none;
opacity: 1;
}
}
// ============================================
// Print Styles
// ============================================
@media print {
.hi-tree {
background: white;
color: black;
box-shadow: none;
border: 1px solid #000;
}
.hi-tree-node-content {
background: transparent;
border: none;
}
.hi-tree-node-content::after,
.hi-tree-node::before {
display: none;
}
}