noteloom 0.1.4 → 0.1.6

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.
package/dist/style.css CHANGED
@@ -155,6 +155,13 @@
155
155
  outline: none;
156
156
  }
157
157
 
158
+ .be-blockquote[dir='rtl'] {
159
+ padding-left: 0;
160
+ padding-right: 0.9em;
161
+ border-left: none;
162
+ border-right: 3px solid var(--noteloom-border);
163
+ }
164
+
158
165
  /* --- callout --- */
159
166
 
160
167
  .be-callout {
@@ -640,6 +647,12 @@
640
647
  color: #fff;
641
648
  }
642
649
 
650
+ .be-embed-alt-text-btn {
651
+ width: auto;
652
+ padding: 0 8px;
653
+ font-size: 0.75rem;
654
+ }
655
+
643
656
  .be-embed-remove {
644
657
  border: none;
645
658
  background: transparent;
@@ -1098,6 +1111,15 @@ tr.be-table-row:hover .be-table-delete-row {
1098
1111
  user-select: none; /* it's a drag handle (see useBlockRangeDrag) — never let its own space become selectable text */
1099
1112
  }
1100
1113
 
1114
+ /* `left`/`right` are physical, not logical, properties — unlike the list
1115
+ marker's flexbox position (which flips for free via dir inheritance),
1116
+ this absolute offset needs an explicit RTL override to sit on the
1117
+ correct side of the block. */
1118
+ [dir='rtl'] .be-block-gutter {
1119
+ left: auto;
1120
+ right: -56px;
1121
+ }
1122
+
1101
1123
  .be-block-row:hover .be-block-gutter,
1102
1124
  .be-block-gutter-active {
1103
1125
  opacity: 1;
@@ -1117,6 +1139,20 @@ tr.be-table-row:hover .be-table-delete-row {
1117
1139
  transition: background-color 0.12s ease, color 0.12s ease;
1118
1140
  }
1119
1141
 
1142
+ /* Touch: no hover state exists to reveal the gutter at all, and its
1143
+ desktop position (left: -56px, sitting in the page's own side margin)
1144
+ would be off-screen on a narrow phone/tablet viewport regardless — so
1145
+ rather than force it into the row itself, its two actions (Add block,
1146
+ block options menu) live inside MobileActionBar instead (see
1147
+ MobileActionBar.jsx), pinned above the keyboard where they're always
1148
+ reachable. `.be-touch-input` is set by useCoarsePointer.js, based on
1149
+ real pointerdown activity, not just a static device-capability guess —
1150
+ see that file for why a plain `pointer: coarse` media query alone isn't
1151
+ enough (touchscreen laptops, etc.). */
1152
+ .be-touch-input .be-block-gutter {
1153
+ display: none;
1154
+ }
1155
+
1120
1156
  .be-block-gutter-btn:hover,
1121
1157
  .be-block-gutter-btn[aria-expanded='true'] {
1122
1158
  background: var(--noteloom-bg-hover);
@@ -1294,6 +1330,132 @@ tr.be-table-row:hover .be-table-delete-row {
1294
1330
  max-width: 640px;
1295
1331
  }
1296
1332
 
1333
+ /* Bottom sheet variant (mobile block picker) — anchored to the bottom edge
1334
+ instead of centered, rounded only on top, full page width. */
1335
+ .be-modal-overlay-sheet {
1336
+ align-items: flex-end;
1337
+ padding: 0;
1338
+ }
1339
+
1340
+ .be-modal-sheet {
1341
+ max-width: 100%;
1342
+ width: 100%;
1343
+ max-height: 70vh;
1344
+ border-radius: var(--noteloom-radius-xl) var(--noteloom-radius-xl) 0 0;
1345
+ border-bottom: none;
1346
+ padding-bottom: max(1.4em, env(safe-area-inset-bottom));
1347
+ }
1348
+
1349
+ .be-mobile-picker-list {
1350
+ display: flex;
1351
+ flex-direction: column;
1352
+ gap: 2px;
1353
+ }
1354
+
1355
+ .be-mobile-picker-item {
1356
+ display: flex;
1357
+ align-items: center;
1358
+ gap: 10px;
1359
+ width: 100%;
1360
+ border: none;
1361
+ background: transparent;
1362
+ border-radius: var(--noteloom-radius-md);
1363
+ padding: 12px 10px;
1364
+ font: inherit;
1365
+ font-size: 0.95rem;
1366
+ color: var(--noteloom-text);
1367
+ text-align: left;
1368
+ cursor: pointer;
1369
+ }
1370
+
1371
+ .be-mobile-picker-item:hover,
1372
+ .be-mobile-picker-item:active {
1373
+ background: var(--noteloom-bg-hover);
1374
+ }
1375
+
1376
+ .be-mobile-picker-item-danger {
1377
+ color: var(--noteloom-danger);
1378
+ }
1379
+
1380
+ .be-mobile-picker-item-danger:hover,
1381
+ .be-mobile-picker-item-danger:active {
1382
+ background: var(--noteloom-danger-soft);
1383
+ }
1384
+
1385
+ .be-mobile-picker-item-danger .be-mobile-picker-item-icon {
1386
+ color: var(--noteloom-danger);
1387
+ }
1388
+
1389
+ /* --- mobile action bar (pinned above the on-screen keyboard) --- */
1390
+
1391
+ .be-mobile-action-bar {
1392
+ position: fixed;
1393
+ left: 0;
1394
+ right: 0;
1395
+ z-index: 1500;
1396
+ display: flex;
1397
+ align-items: center;
1398
+ gap: 2px;
1399
+ padding: 6px calc(6px + env(safe-area-inset-right)) 6px calc(6px + env(safe-area-inset-left));
1400
+ background: var(--noteloom-bg);
1401
+ border-top: 1px solid var(--noteloom-border);
1402
+ overflow-x: auto;
1403
+ }
1404
+
1405
+ .be-mobile-bar-btn {
1406
+ flex: none;
1407
+ display: flex;
1408
+ align-items: center;
1409
+ justify-content: center;
1410
+ gap: 4px;
1411
+ min-width: 40px;
1412
+ height: 40px;
1413
+ padding: 0 10px;
1414
+ border: none;
1415
+ background: transparent;
1416
+ border-radius: var(--noteloom-radius-sm);
1417
+ color: var(--noteloom-text);
1418
+ font-size: 0.85rem;
1419
+ font-weight: 500;
1420
+ cursor: pointer;
1421
+ }
1422
+
1423
+ .be-mobile-bar-btn:disabled {
1424
+ opacity: 0.4;
1425
+ }
1426
+
1427
+ .be-mobile-bar-btn-active {
1428
+ background: var(--noteloom-accent-soft);
1429
+ color: var(--noteloom-accent);
1430
+ }
1431
+
1432
+ .be-mobile-bar-spacer {
1433
+ flex: 1;
1434
+ }
1435
+
1436
+ .be-mobile-bar-select {
1437
+ flex: none;
1438
+ }
1439
+
1440
+ .be-mobile-bar-swatches {
1441
+ display: flex;
1442
+ align-items: center;
1443
+ gap: 6px;
1444
+ padding: 0 6px;
1445
+ }
1446
+
1447
+ .be-mobile-picker-item-icon {
1448
+ flex: none;
1449
+ display: flex;
1450
+ align-items: center;
1451
+ justify-content: center;
1452
+ width: 32px;
1453
+ height: 32px;
1454
+ border-radius: var(--noteloom-radius-sm);
1455
+ background: var(--noteloom-bg-subtle);
1456
+ color: var(--noteloom-text-muted);
1457
+ }
1458
+
1297
1459
  .be-modal-title {
1298
1460
  font-weight: 600;
1299
1461
  font-size: 1.05rem;
@@ -1895,3 +2057,149 @@ tr.be-table-row:hover .be-table-delete-row {
1895
2057
  background: var(--noteloom-bg-hover);
1896
2058
  color: var(--noteloom-text);
1897
2059
  }
2060
+
2061
+ /* --- voice typing: caret-anchored listening/processing indicator --- */
2062
+
2063
+ .be-voice-indicator {
2064
+ z-index: 1000;
2065
+ display: flex;
2066
+ align-items: center;
2067
+ gap: 5px;
2068
+ background: var(--noteloom-bg);
2069
+ border: 1px solid var(--noteloom-border);
2070
+ border-radius: var(--noteloom-radius-md);
2071
+ padding: 4px 9px;
2072
+ box-shadow: var(--noteloom-shadow);
2073
+ font-size: 0.78rem;
2074
+ color: var(--noteloom-text-muted);
2075
+ white-space: nowrap;
2076
+ pointer-events: none;
2077
+ animation: be-voice-indicator-in 0.12s ease-out;
2078
+ }
2079
+
2080
+ @keyframes be-voice-indicator-in {
2081
+ from {
2082
+ opacity: 0;
2083
+ transform: translate(-50%, calc(-100% + 4px));
2084
+ }
2085
+ to {
2086
+ opacity: 1;
2087
+ transform: translate(-50%, -100%);
2088
+ }
2089
+ }
2090
+
2091
+ .be-voice-indicator-dot {
2092
+ width: 7px;
2093
+ height: 7px;
2094
+ border-radius: 50%;
2095
+ background: var(--noteloom-danger, #dc2626);
2096
+ flex: none;
2097
+ animation: be-voice-indicator-pulse 1.4s ease-in-out infinite;
2098
+ }
2099
+
2100
+ .be-voice-indicator-processing .be-voice-indicator-dot {
2101
+ background: var(--noteloom-accent);
2102
+ animation-duration: 0.6s;
2103
+ }
2104
+
2105
+ @keyframes be-voice-indicator-pulse {
2106
+ 0%,
2107
+ 100% {
2108
+ opacity: 1;
2109
+ box-shadow: 0 0 0 0 currentColor;
2110
+ }
2111
+ 50% {
2112
+ opacity: 0.5;
2113
+ box-shadow: 0 0 0 4px transparent;
2114
+ }
2115
+ }
2116
+
2117
+ /* --- print --- */
2118
+ /*
2119
+ * Printing (or "Save as PDF" via the browser's own print dialog — this
2120
+ * package deliberately doesn't bundle a PDF-generation library, which
2121
+ * would conflict with staying zero-runtime-dependency) always renders a
2122
+ * clean, chrome-free document: every piece of editing-only UI is hidden
2123
+ * here, regardless of whether the app happens to be in preview mode at
2124
+ * the moment of printing. `.be-block-row-hidden` is included on purpose —
2125
+ * a block hidden via "Hide in preview" stays in the DOM (just dimmed) in
2126
+ * edit mode, so without this rule printing while NOT toggled into preview
2127
+ * mode would print blocks the user explicitly marked as hidden. A host
2128
+ * app's own outer chrome (nav bars, its own toolbar) needs its own print
2129
+ * rules the same way — see examples/basic's own style.css for a worked
2130
+ * example, since that chrome lives outside this package entirely.
2131
+ */
2132
+ @media print {
2133
+ .be-block-gutter,
2134
+ .be-block-gutter-menu,
2135
+ .be-block-gutter-menu-item,
2136
+ .be-block-range-menu,
2137
+ .be-block-range-menu-item,
2138
+ .be-block-row-hidden,
2139
+ .be-slash-menu,
2140
+ #be-emoji-menu,
2141
+ #be-at-menu,
2142
+ .be-floating-toolbar,
2143
+ .be-link-hover-card,
2144
+ .be-voice-indicator,
2145
+ .be-table-header-menu-trigger,
2146
+ .be-table-header-menu,
2147
+ .be-table-col-resize-handle,
2148
+ .be-table-delete-row,
2149
+ .be-table-add-row,
2150
+ .be-embed-toolbar,
2151
+ .be-embed-remove,
2152
+ .be-embed-resize-handle,
2153
+ .be-embed-dropzone,
2154
+ .be-embed-upload-btn,
2155
+ .be-embed-url-row,
2156
+ .be-callout-color-wrap,
2157
+ .be-modal-overlay,
2158
+ .be-mobile-action-bar,
2159
+ .be-mobile-picker-list,
2160
+ .be-export-trigger,
2161
+ .be-export-tabs,
2162
+ .be-trailing-space,
2163
+ .be-select-popover {
2164
+ display: none !important;
2165
+ }
2166
+
2167
+ /* .be-block-row-range-selected and .be-block-selected mark real content
2168
+ (the row/block itself, not a standalone chrome element) with a
2169
+ highlight background/outline — reset just that styling rather than
2170
+ hiding the element the way the chrome above is hidden, or printing
2171
+ mid-drag-selection would print blank space instead of the block's own
2172
+ content. */
2173
+ .be-block-row-range-selected {
2174
+ background: none !important;
2175
+ }
2176
+
2177
+ .be-block-selected {
2178
+ outline: none !important;
2179
+ }
2180
+
2181
+ /* No background colors/shadows on paper, and text that's always legible
2182
+ regardless of the screen theme the page happened to be rendered in
2183
+ (dark mode's near-white text would otherwise print as barely-there). */
2184
+ .be-editable,
2185
+ .be-paragraph,
2186
+ .be-heading,
2187
+ .be-list-item,
2188
+ .be-blockquote,
2189
+ .be-code-block,
2190
+ .be-callout,
2191
+ .be-table-cell {
2192
+ background: none !important;
2193
+ box-shadow: none !important;
2194
+ color: #000 !important;
2195
+ }
2196
+
2197
+ /* Don't split a table/code block/callout/image awkwardly across a page
2198
+ boundary when it would otherwise fit on one page. */
2199
+ .be-table,
2200
+ .be-code-block,
2201
+ .be-callout,
2202
+ .be-embed-image {
2203
+ break-inside: avoid;
2204
+ }
2205
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noteloom",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Zero-runtime-dependency, React-first block/rich-text editor — Notion-style blocks, inline widgets, slash commands, undo/redo, and clipboard, with an optional default theme (noteloom/style.css).",
5
5
  "keywords": [
6
6
  "react",