CSS/Sass Module :- attr doesn't work inside url - css-modules

I have a Scss Code like this:
.section-features {
padding: 20rem 0;
background-size: cover;
background-position: center;
margin-top: 6rem;
transform: skewY(-5deg);
&::before {
content: attr(data-src);
}
background-image: url(attr(data-src));
/* background-image: linear-gradient(
to right bottom,
rgba(126, 213, 111, 0.8),
rgba(40, 180, 133, 0.8)
),
url($default-image-features-section-bg); */
& > * {
transform: skewY(5deg);
}
}
You can see that when I use attr property with content it works as expected. However when I do the same with url property:
.section-features {
padding: 20rem 0;
background-size: cover;
background-position: center;
margin-top: 6rem;
transform: skewY(-5deg);
&::before {
content: attr(data-src);
}
background-image: url(attr(data-src));
/* background-image: linear-gradient(
to right bottom,
rgba(126, 213, 111, 0.8),
rgba(40, 180, 133, 0.8)
),
url(attr(data-src,$default-image-features-section-bg)); */
& > * {
transform: skewY(5deg);
}
}
It throws me following error:
./components/MainSection/Main.module.scss:4:0
Module not found: Can't resolve './attr(data-src'
Import trace for requested module:
./components/MainSection/Main.module.scss
./components/MainSection/index.tsx
./components/index.tsx
./pages/index.tsx
https://nextjs.org/docs/messages/module-not-found
I am using "sass": "^1.53.0" can someone help me sort this out? I am running it as a sass module in NEXT JS.
Even if I tried the same in a normal CSS module it won't work there as well.

Related

Add file list, delete and download in ESP32 simple file server

It's the first time to ask a question, please forgive me if I am wrong.
English is not my native language; please excuse typing errors.
I am using ESP32 for the first time. I want to be a file server, but now it only has upload function. I want to add download, delete and file list. I have not been able to find suitable information. thank you.
ESP32 code:
#include <Arduino.h>
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <SPI.h>
#include <SPIFFS.h>
void setup() {
Serial.begin(115200);
if(!SPIFFS.begin()){
Serial.println("An Error has occurred while mounting SPIFFS");
}
start_access_point();
start_web_server();
}
void loop()
{
}
const char* ap_ssid = "ESP32";
const char* ap_pwd = "12345678";
void start_access_point(){
WiFi.softAP(ap_ssid, ap_pwd);
IPAddress myIP = WiFi.softAPIP();
Serial.println("Access point started");
Serial.print("AP IP address: ");
Serial.println(myIP);
}
AsyncWebServer server(80);
const char* PARAM_SSID = "ssid";
const char* PARAM_PWD = "pwd";
void start_web_server(){
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html", "text/html");
});
server.on("/upload", HTTP_POST, [](AsyncWebServerRequest *request){
if(request->hasArg("file")){
String fileName = request->arg("file");
File f = SPIFFS.open("/data/fileName", "w");
if(!f){
request->send(500, "text/plain", "Could not open file for writing");
return;
}
std::string fileData = std::string(request->arg("file").c_str());
f.write((uint8_t*)fileData.c_str(), fileData.length());
f.close();
request->send(200, "text/plain", "File uploaded successfully");
}
else{
request->send(500, "text/plain", "No file data found in request");
}
});
server.begin();
}
HTML:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<style>.app-container{
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
h3{
text-align: center;
color: #5a5c69 !important;
font-family: Arial, Helvetica, sans-serif;
}
/* Style inputs, select elements and textareas */
input[type=text], select, textarea{
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
resize: vertical;
}
input[type=password], select, textarea{
width: 100%;
padding: 12px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
resize: vertical;
}
/* Style the label to display next to the inputs */
label {
padding: 12px 12px 12px 0;
display: inline-block;
}
/* Style the submit button */
input[type=submit] {
background-color: #4CAF50;
color: white;
padding: 12px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
float: right;
}
/* Floating column for labels: 25% width */
.col-25 {
float: left;
width: 25%;
margin-top: 6px;
}
/* Floating column for inputs: 75% width */
.col-75 {
float: left;
width: 75%;
margin-top: 6px;
}
/* Clear floats after the columns */
.row:after {
content: "";
display: table;
clear: both;
}
/* Responsive layout - when the screen is less than 600px wide, make the two columns stack on top of each other instead of next to each other */
#media screen and (max-width: 600px) {
.col-25, .col-75, input[type=submit] {
width: 100%;
margin-top: 0;
}
}
</style>
<title id="apptitle">Setup Wifi</title>
<head>
<title>File Upload</title>
</head>
<body>
<h1>File Upload</h1>
<form method="post" action="/upload" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
Download file
</body>
</html>
I tried to find a similar function modification on github, but there was no way
List. Simple iteration through all files in the data folder of esp32. Absolute path deletion before file name has to be done manually if you just want the file names:
#include "SPIFFS.h"
void setup() {
Serial.begin(115200);
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file){
Serial.print("FILE: ");
Serial.println(file.name());
file = root.openNextFile();
}
}
void loop() {}
Delete:
SPIFFS.remove(path); (all paths are absolute paths)
exists function to check if file exists
mkdir creating new folder
rmdir remove folder
opendir
rename
info
and more can be found here. just scroll down enough until you find them in the documentation:
https://arduino-esp8266.readthedocs.io/en/latest/filesystem.html
Edit: Forgot to add download here. Download can be accomplished similarly to what you already have for your API:
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(SPIFFS, "/index.html", "text/html");
});
It could send you to a new tab with the new link and use the response as a download buffer type thing. But change the type to the type of file you want. Im not quite sure what the name of the type was but i think it was something on the line of "binary/png" or something. you'd have to search that up

What RegEx to select comma separated CSS selectors individually in SublimeText?

The other day I had to prefix every single CSS selector with another tag in order to increase its specificity. I though I'd flex my regex muscles a bit and I came up with this regex:
(^(((\s)+)?(?!.+: )(?!\.IE)[a-z.].+?)([,{]))
The plan was to replace the entire captured match with something like 'body $1'. There are a couple of negative lookaheads to avoid matching lines like background-color: property and .IE selectors
The screenshot describes the problem:
Here is some sample text:
/* line 18, ../scss/SplashPage/_page.scss */
* {
-webkit-tap-highlight-color: transparent;
}
/* line 35, ../scss/SplashPage/_page.scss */
body header {
*zoom: 1;
background: #eaeaea;
}
/* line 221, ../scss/MainStyle/_mixins.scss */
body header:before, body header:after {
display: table;
content: "";
}
/* line 224, ../scss/MainStyle/_mixins.scss */
body header:after {
clear: both;
}
body .utility-nav {
right:0
}
/* line 40, ../scss/SplashPage/_page.scss */
body .home-link {
text-indent: -99999px;
white-space: nowrap;
overflow: hidden;
background: transparent url("~/images/clipsal-logo2.png") center center no-repeat;
background-image: -webkit-linear-gradient(transparent, transparent), url("~/images/clipsal-logo.svg");
background-image: linear-gradient(transparent, transparent), url("~/images/clipsal-logo.svg");
background-position: top left;
background-repeat: no-repeat;
display: block;
float: left;
/*width: 120px;
height: 50px;
margin: 20px 0px 15px 25px;*/
background-size: 100% auto;
}
I think it's the start of line anchor (^) that needs do be dropped. Having said that I am not sure what the regex should be :)
Note: I understand that the problem could have easily been solved using SASS, but where's the fun in that!
Thanks

nnnick chart.js - Custom Tooltip on Line Chart

We are using nnnick chart.js (open source chart) in our application for reporting purpose.There is a requirement to show the Custom tool-tip in the line chart.
As of now , Normal chart tooltip is showing based on the X-axis and Y axis dataset values. But Here we want to show the Dynamic additional data in the Tooltip.
For Example ,
Let us take a Student Enrollment .
here
X Axis Value - Enrollment Month (Jan,Feb,Mar....etc)
Y Axis Value - Number of Enrollments (10,20,30...ect)
After the Line chart is plotted , Now it is displaying (Jan ,10) in the tooltip.
We have to show the Number of Male & Female student details in the tool tip On mouse over the data point Jan 10 (i.e) (Jan,10, Male:5 , Female 5 ).
If you see the above screen shot , Green color is toop-tip is the normal one which is a built-in option. Red Color highlighted tool-tip is the one we are expecting.
Please provide any suggestion on this .
So you can achieve this using the custom tool tip function in the newer (not sure when it was included) version of chart js. You can have it display anything you want in place of a normal tooltip so in this case i have added a tooltip and a tooltip-overview.
The really annoying thing is though in this function you are not told which index you are currently showing a tooltip for. Two ways to solve this, override the showToolTip function so it actually passes this information or do a quick little hack to extract the label from the tooltip text and get the index from the labels array (hacky but quicker so i went for this one in the example)
So here is a quick example based upon the samples in chartjs samples folder. This is just a quick example so you would prob need to play around with the positioning and stuff until its what you need.
Chart.defaults.global.pointHitDetectionRadius = 1;
Chart.defaults.global.customTooltips = function(tooltip) {
// Tooltip Element
var tooltipEl = $('#chartjs-tooltip');
var tooltipOverviewEl = $('#chartjs-tooltip-overview');
// Hide if no tooltip
if (!tooltip) {
tooltipEl.css({
opacity: 0
});
tooltipOverviewEl.css({
opacity: 0
});
return;
}
//really annoyingly we don;t get told which index this comes from so going to have
//to extract the label from the text :( and then find the index based on that
//other option here is to override the the whole showTooltip in chartjs and have the index passed
var label = tooltip.text.substr(0, tooltip.text.indexOf(':'));
var labelIndex = labels.indexOf(label);
var maleEnrolmentNumber = maleEnrolments[labelIndex];
var femaleEnrolmentNumber = FemaleEnrolments[labelIndex];
// Set caret Position
tooltipEl.removeClass('above below');
tooltipEl.addClass(tooltip.yAlign);
// Set Text
tooltipEl.html(tooltip.text);
//quick an ddirty could use an actualy template here
var tooltipOverviewElHtml = "<div> Overall : " + (maleEnrolmentNumber + femaleEnrolmentNumber) + "</div>";
tooltipOverviewElHtml += "<div> Male : " + (maleEnrolmentNumber) + "</div>";
tooltipOverviewElHtml += "<div> Female : " + (femaleEnrolmentNumber) + "</div>";
tooltipOverviewEl.html(tooltipOverviewElHtml);
// Find Y Location on page
var top;
if (tooltip.yAlign == 'above') {
top = tooltip.y - tooltip.caretHeight - tooltip.caretPadding;
} else {
top = tooltip.y + tooltip.caretHeight + tooltip.caretPadding;
}
// Display, position, and set styles for font
tooltipEl.css({
opacity: 1,
left: tooltip.chart.canvas.offsetLeft + tooltip.x + 'px',
top: tooltip.chart.canvas.offsetTop + top + 'px',
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
tooltipOverviewEl.css({
opacity: 1,
fontFamily: tooltip.fontFamily,
fontSize: tooltip.fontSize,
fontStyle: tooltip.fontStyle,
});
};
var maleEnrolments = [5, 20, 15, 20, 20, 30, 50]; // Integer array for male each value is corresponding to each month
var FemaleEnrolments = [5, 0, 15, 20, 30, 30, 20]; // Integer array for Female each value is corresponding to each month
var labels = ["Jan", "February", "March", "April", "May", "June", "July"]; //Enrollment by Month
var lineChartData = {
labels: labels,
datasets: [{
label: "Student Details",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: [10, 20, 30, 40, 50, 60, 70], //enrollement Details overall (Male + Female)
}]
};
var ctx2 = document.getElementById("chart2").getContext("2d");
window.myLine = new Chart(ctx2).Line(lineChartData, {
responsive: true
});
#canvas-holder1 {
width: 300px;
margin: 20px auto;
}
#canvas-holder2 {
width: 50%;
margin: 20px 25%;
position:relative;
}
#chartjs-tooltip-overview {
opacity: 0;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
left:200px;
top:0px
}
#chartjs-tooltip {
opacity: 1;
position: absolute;
background: rgba(0, 0, 0, .7);
color: white;
padding: 3px;
border-radius: 3px;
-webkit-transition: all .1s ease;
transition: all .1s ease;
pointer-events: none;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
}
.chartjs-tooltip-key {
display:inline-block;
width:10px;
height:10px;
}
<script src="https://raw.githack.com/nnnick/Chart.js/master/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="canvas-holder2">
<div id="chartjs-tooltip-overview"></div>
<div id="chartjs-tooltip"></div>
<canvas id="chart2" width="600" height="600" />
</div>

Scrollable Foundation Section headers

Looking through http://foundation.zurb.com/docs/components/section.html, is there anyway I can add horizontal scroll for Section headers ( Tabs) . I am looking something like http://www.seyfertdesign.com/jquery/ui.tabs.paging.html in foundation sections with horizontal scroll and continue to use accordion in small screen
I found a solution for those interested : https://codepen.io/gdyrrahitis/pen/BKyKGe
.tabs {
overflow-x: auto;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
.tabs-title {
float: none;
display: inline-block;
}
}
if someone needs an angularjs with jquery implementation, below code can help you, for pure jquery replace angularjs directive method with a native js method with respective attributes.
I tried to search for similar implementation but found nothing, so I have written a simple angular directive which can transform a foundation CSS tabs to scrollable tabs
angular.module("app.directives.scrollingTabs", [])
.directive("scrollingTabs", ScrollingTabsDirective);
//#ngInject
function ScrollingTabsDirective($timeout, $window) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if(attr.scrollingTabs == "true"){
element.addClass('scrolling-tabs-container');
element.find('.nav-buttons').remove();
element.append('<div class="scrolling-tabs nav-buttons nav-buttons-left"></div>');
element.append('<div class="scrolling-tabs nav-buttons nav-buttons-right"></div>');
let scrolledDiv = $(element).find('.tabs');
let scrolled;
let scrolling;
let scrollFn = (step, animationTime, cb) => {
scrolled = Math.max(scrolled + step, 0);
scrolledDiv.animate({
scrollLeft: scrolled
}, animationTime, ()=>{
if (scrolling) {
scrollFn(step, animationTime, cb)
}else{
if(cb){cb()}
}
});
};
let checkActiveNavButtonsClasses = () => {
scrolled = scrolledDiv.scrollLeft();
let scrollWidth = scrolledDiv.get(0).scrollWidth;
let scrolledDivWidth = scrolledDiv.get(0).clientWidth;
if(scrollWidth > scrolledDivWidth){
element.addClass('nav-active');
scrollWidth = scrolledDiv.get(0).scrollWidth;
if(scrolled == 0){
element.removeClass('nav-active-left').addClass('nav-active-right')
}else if(scrolled > 0 && scrolled + scrollWidth < scrolledDivWidth){
element.addClass('nav-active-left').addClass('nav-active-right');
}else if(scrolled > 0 && scrolled + scrollWidth >= scrolledDivWidth){
element.addClass('nav-active-left').removeClass('nav-active-right');
}else{
element.removeClass('nav-active-left').removeClass('nav-active-right')
}
}else{
element.removeClass('nav-active-left').removeClass('nav-active-right').removeClass('nav-active');
}
};
let scrollToActiveTab = () => {
let activeDD = scrolledDiv.find('dd.active');
let tabsOffset = scrolledDiv.offset();
let activeTaboffset = activeDD.offset();
let activeTabwidth = activeDD.width();
let scrolledStep = activeTaboffset.left - tabsOffset.left - scrolledDiv.width() + activeTabwidth;
scrollFn(scrolledStep, 100, checkActiveNavButtonsClasses);
};
element.find(".nav-buttons.nav-buttons-left")
.off("click.scrolling")
.on("click.scrolling", (event)=>{
event.preventDefault();
scrolling = false;
scrollFn(-100, 100, checkActiveNavButtonsClasses);
})
.off("mouseover.scrolling")
.on("mouseover.scrolling", function (event) {
scrolling = true;
scrollFn(-2, 1, checkActiveNavButtonsClasses);
})
.off("mouseout.scrolling")
.on("mouseout.scrolling", function (event) {
scrolling = false;
});
element.find(".nav-buttons.nav-buttons-right")
.off("click.scrolling")
.on("click.scrolling", (event)=>{
event.preventDefault();
scrolling = false;
scrollFn(100, 100, checkActiveNavButtonsClasses);
})
.off("mouseover.scrolling")
.on("mouseover.scrolling", function (event) {
scrolling = true;
scrollFn(2, 1, checkActiveNavButtonsClasses);
})
.off("mouseout.scrolling")
.on("mouseout.scrolling", function (event) {
scrolling = false;
});
$timeout(()=>{
checkActiveNavButtonsClasses();
scrollToActiveTab()
},1000);
$($window).off('resize.scrolling').on('resize.scrolling', _.debounce(()=> {
checkActiveNavButtonsClasses();
}, 500));
scope.$on('$destroy', function() {
$($window).off('resize.scrolling');
});
}
}
}}
css:
.scrolling-tabs-container {
position: relative;
.tabs {
overflow-x: hidden;
white-space: nowrap;
-webkit-overflow-scrolling: touch;
display: block;
margin-right: 18px;
dd {
display: inline-block;
float: none;
margin: 0px -3px 0px 0px;
}
.tabs-title {
float: none;
display: inline-block;
}
}
.scrolling-tabs {
&.nav-buttons {
display: none;
position: absolute;
width: 19px;
height: 38px;
border: 1px solid #c1c1c1;
top: 1px;
background-color: rgba(255, 255, 255, 0.5);
opacity: 0.4;
cursor: pointer;
&:hover {
opacity: 1;
&:before {
color: #444;
}
}
&:before {
position: absolute;
left: 7px;
top: 8px;
color: #777;
}
&.nav-buttons-left {
left: 0;
&:before {
content: '<';
}
}
&.nav-buttons-right {
right: 18px;
&:before {
content: '>';
}
}
}
}
&.nav-active{
.tabs{
margin-right: 36px;
margin-left: 18px;
}
.scrolling-tabs {
&.nav-buttons {
display: inline-block !important;
}
}
}
&.nav-active-left{
.scrolling-tabs{
&.nav-buttons-left{
opacity: 0.8;
}
}
}
&.nav-active-right{
.scrolling-tabs{
&.nav-buttons-right{
opacity: 0.8;
}
}}}
HTML: Foundation Tabs template.
<tabset class="list-tabs" scrolling-tabs="true">
<tab heading="tab1"></tab>
<tab heading="tab2"></tab>
<tab heading="tab2"></tab>
</tabset>
Before you start you'll want to verify that both jQuery (or Zepto) and foundation.js are available on your page. These come with foundation package so just uncomment them in your footer or include them accordingly.
<div class="section-container auto" data-section>
<section class="active">
<p class="title" data-section-title>Section 1</p>
<div class="content" data-section-content>
<p>Content of section 1.</p>
</div>
</section>
<section>
<p class="title" data-section-title>Section 2</p>
<div class="content" data-section-content>
<p>Content of section 2.</p>
</div>
</section>
</div>
The foundation documentation has all of the information for this :
http://foundation.zurb.com/docs/components/section.html#panel2
This will get you your section tabular headers. You then want to manage the content to be scrollable.
<div class="content" data-section-content>
<p>Content of section 1.</p>
</div>
This content here will be the area to work on, try adding a new class called .scrollable
Within this class use something like:
.scrollable{
overflow:scroll;
}
You may want to add some more to this however this will get you started. Your HTML should now look like this :
<div class="content scrollable" data-section-content>
<p>Content of section 1. This content will be scrollable when the content has exceeded that of the div size. </p>
</div>
This this is what you are looking for.

height auto css issue

I tried to set the height of my webpage to auto with no success. When the text grows, it overlaps the footer. Any ideas where I am getting it wrong? I want to extend the .main class when the text grows.
.main {
background-position: right bottom;
min-height: 1200px;
background-color: #FFFFFF;
background-image: url('../images/side-shape.png');
background-repeat: no-repeat;
height:auto !Important;
}
just remove this line from your footer class
margin-top: -175px;
Looks like you need to clear the float you have in your left column. Put clear: both; in your footer_wrapper and that should fix this.